add destIp support for NAT
This commit is contained in:
parent
aea2e74ef8
commit
56d1c42f7e
|
@ -0,0 +1,68 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TDengine only supports a subset of the standard SQL, thus this implemetation of the
|
||||||
|
* standard JDBC API contains more or less some adjustments customized for certain
|
||||||
|
* compatibility needs.
|
||||||
|
*/
|
||||||
|
public class CatalogResultSet extends TSDBResultSetWrapper {
|
||||||
|
|
||||||
|
|
||||||
|
public CatalogResultSet(ResultSet resultSet) {
|
||||||
|
super.setOriginalResultSet(resultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(int columnIndex) throws SQLException {
|
||||||
|
if (columnIndex <= 1) {
|
||||||
|
return super.getString(columnIndex);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBoolean(int columnIndex) throws SQLException {
|
||||||
|
if (columnIndex <= 1) {
|
||||||
|
return super.getBoolean(columnIndex);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBytes(int columnIndex) throws SQLException {
|
||||||
|
if (columnIndex <= 1) {
|
||||||
|
return super.getBytes(columnIndex);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getObject(int columnIndex) throws SQLException {
|
||||||
|
if (columnIndex <= 1) {
|
||||||
|
return super.getObject(columnIndex);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
public class ColumnMetaData {
|
||||||
|
|
||||||
|
int colType = 0;
|
||||||
|
String colName = null;
|
||||||
|
int colSize = -1;
|
||||||
|
int colIndex = 0;
|
||||||
|
|
||||||
|
public int getColSize() {
|
||||||
|
return colSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColSize(int colSize) {
|
||||||
|
this.colSize = colSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColType() {
|
||||||
|
return colType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColType(int colType) {
|
||||||
|
this.colType = colType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getColName() {
|
||||||
|
return colName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColName(String colName) {
|
||||||
|
this.colName = colName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColIndex() {
|
||||||
|
return colIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColIndex(int colIndex) {
|
||||||
|
this.colIndex = colIndex;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,986 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TDengine only supports a subset of the standard SQL, thus this implemetation of the
|
||||||
|
* standard JDBC API contains more or less some adjustments customized for certain
|
||||||
|
* compatibility needs.
|
||||||
|
*/
|
||||||
|
public class EmptyResultSet implements ResultSet {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean next() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wasNull() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBoolean(int columnIndex) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getByte(int columnIndex) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short getShort(int columnIndex) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(int columnIndex) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLong(int columnIndex) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getFloat(int columnIndex) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDouble(int columnIndex) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBytes(int columnIndex) throws SQLException {
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getDate(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Time getTime(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timestamp getTimestamp(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getAsciiStream(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getBinaryStream(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBoolean(String columnLabel) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getByte(String columnLabel) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short getShort(String columnLabel) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(String columnLabel) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLong(String columnLabel) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getFloat(String columnLabel) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDouble(String columnLabel) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBytes(String columnLabel) throws SQLException {
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getDate(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Time getTime(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timestamp getTimestamp(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getAsciiStream(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getBinaryStream(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SQLWarning getWarnings() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearWarnings() throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCursorName() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSetMetaData getMetaData() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getObject(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getObject(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int findColumn(String columnLabel) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Reader getCharacterStream(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Reader getCharacterStream(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBeforeFirst() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAfterLast() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFirst() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLast() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeFirst() throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterLast() throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean first() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean last() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRow() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean absolute(int row) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean relative(int rows) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean previous() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFetchDirection(int direction) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFetchDirection() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFetchSize(int rows) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFetchSize() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getType() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getConcurrency() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean rowUpdated() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean rowInserted() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean rowDeleted() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNull(int columnIndex) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBoolean(int columnIndex, boolean x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateByte(int columnIndex, byte x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateShort(int columnIndex, short x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateInt(int columnIndex, int x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLong(int columnIndex, long x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateFloat(int columnIndex, float x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDouble(int columnIndex, double x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateString(int columnIndex, String x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBytes(int columnIndex, byte[] x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDate(int columnIndex, Date x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTime(int columnIndex, Time x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateObject(int columnIndex, Object x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNull(String columnLabel) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBoolean(String columnLabel, boolean x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateByte(String columnLabel, byte x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateShort(String columnLabel, short x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateInt(String columnLabel, int x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLong(String columnLabel, long x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateFloat(String columnLabel, float x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDouble(String columnLabel, double x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateString(String columnLabel, String x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBytes(String columnLabel, byte[] x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDate(String columnLabel, Date x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTime(String columnLabel, Time x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateObject(String columnLabel, Object x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insertRow() throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRow() throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteRow() throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void refreshRow() throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelRowUpdates() throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveToInsertRow() throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveToCurrentRow() throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Statement getStatement() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getObject(int columnIndex, Map<String, Class<?>> map) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Ref getRef(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Blob getBlob(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Clob getClob(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Array getArray(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Ref getRef(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Blob getBlob(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Clob getClob(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Array getArray(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getDate(int columnIndex, Calendar cal) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getDate(String columnLabel, Calendar cal) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Time getTime(int columnIndex, Calendar cal) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Time getTime(String columnLabel, Calendar cal) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getURL(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getURL(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRef(int columnIndex, Ref x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRef(String columnLabel, Ref x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBlob(int columnIndex, Blob x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBlob(String columnLabel, Blob x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateClob(int columnIndex, Clob x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateClob(String columnLabel, Clob x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateArray(int columnIndex, Array x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateArray(String columnLabel, Array x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RowId getRowId(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RowId getRowId(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRowId(int columnIndex, RowId x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRowId(String columnLabel, RowId x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHoldability() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClosed() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNString(int columnIndex, String nString) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNString(String columnLabel, String nString) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNClob(String columnLabel, NClob nClob) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NClob getNClob(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NClob getNClob(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SQLXML getSQLXML(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SQLXML getSQLXML(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNString(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNString(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Reader getNCharacterStream(int columnIndex) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Reader getNCharacterStream(String columnLabel) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateClob(int columnIndex, Reader reader) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateClob(String columnLabel, Reader reader) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNClob(int columnIndex, Reader reader) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNClob(String columnLabel, Reader reader) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TDengine only supports a subset of the standard SQL, thus this implemetation of the
|
||||||
|
* standard JDBC API contains more or less some adjustments customized for certain
|
||||||
|
* compatibility needs.
|
||||||
|
*/
|
||||||
|
public class GetColumnsResultSet extends TSDBResultSetWrapper {
|
||||||
|
private String catalog;
|
||||||
|
private String schemaPattern;
|
||||||
|
private String tableNamePattern;
|
||||||
|
private String columnNamePattern;
|
||||||
|
|
||||||
|
public GetColumnsResultSet(ResultSet resultSet, String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) {
|
||||||
|
super.setOriginalResultSet(resultSet);
|
||||||
|
this.catalog = catalog;
|
||||||
|
this.schemaPattern = schemaPattern;
|
||||||
|
this.tableNamePattern = tableNamePattern;
|
||||||
|
this.columnNamePattern = columnNamePattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(int columnIndex) {
|
||||||
|
switch (columnIndex) {
|
||||||
|
case 1:
|
||||||
|
return catalog;
|
||||||
|
case 2:
|
||||||
|
return null;
|
||||||
|
case 3:
|
||||||
|
return tableNamePattern;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TDengine only supports a subset of the standard SQL, thus this implemetation of the
|
||||||
|
* standard JDBC API contains more or less some adjustments customized for certain
|
||||||
|
* compatibility needs.
|
||||||
|
*/
|
||||||
|
public class GetTablesResultSet extends TSDBResultSetWrapper {
|
||||||
|
|
||||||
|
private String catalog;
|
||||||
|
private String schemaPattern;
|
||||||
|
private String tableNamePattern;
|
||||||
|
private String[] types;
|
||||||
|
|
||||||
|
public GetTablesResultSet(ResultSet resultSet, String catalog, String schemaPattern, String tableNamePattern, String[] types) {
|
||||||
|
super.setOriginalResultSet(resultSet);
|
||||||
|
this.catalog = catalog;
|
||||||
|
this.schemaPattern = schemaPattern;
|
||||||
|
this.tableNamePattern = tableNamePattern;
|
||||||
|
this.types = types;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(int columnIndex) throws SQLException {
|
||||||
|
String ret = null;
|
||||||
|
switch (columnIndex) {
|
||||||
|
case 3:
|
||||||
|
return super.getString(1);
|
||||||
|
case 4:
|
||||||
|
return "table";
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,453 @@
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.bean.TSDBPreparedParam;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this class is used to precompile the sql of tdengine insert or import ops
|
||||||
|
*/
|
||||||
|
public class SavedPreparedStatement {
|
||||||
|
|
||||||
|
private TSDBPreparedStatement tsdbPreparedStatement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sql param List
|
||||||
|
*/
|
||||||
|
private List<TSDBPreparedParam> sqlParamList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init param according the sql
|
||||||
|
*/
|
||||||
|
private TSDBPreparedParam initPreparedParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is table name dynamic in the prepared sql
|
||||||
|
*/
|
||||||
|
private boolean isTableNameDynamic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insert or import sql template pattern, the template are the following:
|
||||||
|
* <p>
|
||||||
|
* insert/import into tableName [(field1, field2, ...)] [using stables tags(?, ?, ...) ] values(?, ?, ...) (?, ?, ...)
|
||||||
|
* <p>
|
||||||
|
* we split it to three part:
|
||||||
|
* 1. prefix, insert/import
|
||||||
|
* 2. middle, tableName [(field1, field2, ...)] [using stables tags(?, ?, ...) ]
|
||||||
|
* 3. valueList, the content after values, for example (?, ?, ...) (?, ?, ...)
|
||||||
|
*/
|
||||||
|
private Pattern sqlPattern = Pattern.compile("(?s)(?i)^\\s*(INSERT|IMPORT)\\s+INTO\\s+((?<tablename>\\S+)\\s*(\\(.*\\))?\\s+(USING\\s+(?<stableName>\\S+)\\s+TAGS\\s*\\((?<tagValue>.+)\\))?)\\s*VALUES\\s*(?<valueList>\\(.*\\)).*");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the raw sql template
|
||||||
|
*/
|
||||||
|
private String sql;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the prefix part of sql
|
||||||
|
*/
|
||||||
|
private String prefix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the middle part of sql
|
||||||
|
*/
|
||||||
|
private String middle;
|
||||||
|
|
||||||
|
private int middleParamSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the valueList part of sql
|
||||||
|
*/
|
||||||
|
private String valueList;
|
||||||
|
|
||||||
|
private int valueListSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default param value
|
||||||
|
*/
|
||||||
|
private static final String DEFAULT_VALUE = "NULL";
|
||||||
|
|
||||||
|
private static final String PLACEHOLDER = "?";
|
||||||
|
|
||||||
|
private String tableName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is the parameter add to batch list
|
||||||
|
*/
|
||||||
|
private boolean isAddBatch;
|
||||||
|
|
||||||
|
public SavedPreparedStatement(String sql, TSDBPreparedStatement tsdbPreparedStatement) throws SQLException {
|
||||||
|
this.sql = sql;
|
||||||
|
this.tsdbPreparedStatement = tsdbPreparedStatement;
|
||||||
|
this.sqlParamList = new ArrayList<>();
|
||||||
|
|
||||||
|
parsePreparedParam(this.sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse the init param according the sql param
|
||||||
|
*
|
||||||
|
* @param sql
|
||||||
|
*/
|
||||||
|
private void parsePreparedParam(String sql) throws SQLException {
|
||||||
|
|
||||||
|
Matcher matcher = sqlPattern.matcher(sql);
|
||||||
|
|
||||||
|
if (matcher.find()) {
|
||||||
|
|
||||||
|
tableName = matcher.group("tablename");
|
||||||
|
|
||||||
|
if (tableName != null && PLACEHOLDER.equals(tableName)) {
|
||||||
|
// the table name is dynamic
|
||||||
|
this.isTableNameDynamic = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix = matcher.group(1);
|
||||||
|
middle = matcher.group(2);
|
||||||
|
valueList = matcher.group("valueList");
|
||||||
|
|
||||||
|
if (middle != null && !"".equals(middle)) {
|
||||||
|
middleParamSize = parsePlaceholder(middle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueList != null && !"".equals(valueList)) {
|
||||||
|
valueListSize = parsePlaceholder(valueList);
|
||||||
|
}
|
||||||
|
|
||||||
|
initPreparedParam = initDefaultParam(tableName, middleParamSize, valueListSize);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// not match
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg("the sql is not complete!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private TSDBPreparedParam initDefaultParam(String tableName, int middleParamSize, int valueListSize) {
|
||||||
|
|
||||||
|
TSDBPreparedParam tsdbPreparedParam = new TSDBPreparedParam(tableName);
|
||||||
|
|
||||||
|
tsdbPreparedParam.setMiddleParamList(getDefaultParamList(middleParamSize));
|
||||||
|
|
||||||
|
tsdbPreparedParam.setValueList(getDefaultParamList(valueListSize));
|
||||||
|
|
||||||
|
return tsdbPreparedParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate the default param value list
|
||||||
|
*
|
||||||
|
* @param paramSize
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List<Object> getDefaultParamList(int paramSize) {
|
||||||
|
|
||||||
|
List<Object> paramList = new ArrayList<>(paramSize);
|
||||||
|
if (paramSize > 0) {
|
||||||
|
for (int i = 0; i < paramSize; i++) {
|
||||||
|
paramList.add(i, DEFAULT_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return paramList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calculate the placeholder num
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int parsePlaceholder(String value) {
|
||||||
|
|
||||||
|
Pattern pattern = Pattern.compile("[?]");
|
||||||
|
|
||||||
|
Matcher matcher = pattern.matcher(value);
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
while (matcher.find()) {
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set current row params
|
||||||
|
*
|
||||||
|
* @param parameterIndex the first parameter is 1, the second is 2, ...
|
||||||
|
* @param x the parameter value
|
||||||
|
*/
|
||||||
|
public void setParam(int parameterIndex, Object x) throws SQLException {
|
||||||
|
|
||||||
|
int paramSize = this.middleParamSize + this.valueListSize;
|
||||||
|
|
||||||
|
String errorMsg = String.format("the parameterIndex %s out of the range [1, %s]", parameterIndex, paramSize);
|
||||||
|
|
||||||
|
if (parameterIndex < 1 || parameterIndex > paramSize) {
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg(errorMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isAddBatch = false; //set isAddBatch to false
|
||||||
|
|
||||||
|
if (x == null) {
|
||||||
|
x = DEFAULT_VALUE; // set default null string
|
||||||
|
}
|
||||||
|
|
||||||
|
parameterIndex = parameterIndex - 1; // start from 0 in param list
|
||||||
|
|
||||||
|
if (this.middleParamSize > 0 && parameterIndex >= 0 && parameterIndex < this.middleParamSize) {
|
||||||
|
|
||||||
|
this.initPreparedParam.setMiddleParam(parameterIndex, x);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.valueListSize > 0 && parameterIndex >= this.middleParamSize && parameterIndex < paramSize) {
|
||||||
|
|
||||||
|
this.initPreparedParam.setValueParam(parameterIndex - this.middleParamSize, x);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg(errorMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBatch() {
|
||||||
|
|
||||||
|
addCurrentRowParamToList();
|
||||||
|
this.initPreparedParam = initDefaultParam(tableName, middleParamSize, valueListSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add current param to batch list
|
||||||
|
*/
|
||||||
|
private void addCurrentRowParamToList() {
|
||||||
|
|
||||||
|
if (initPreparedParam != null && (this.middleParamSize > 0 || this.valueListSize > 0)) {
|
||||||
|
this.sqlParamList.add(initPreparedParam); // add current param to batch list
|
||||||
|
}
|
||||||
|
this.isAddBatch = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* execute the sql with batch sql
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public int[] executeBatch() throws SQLException {
|
||||||
|
|
||||||
|
int result = executeBatchInternal();
|
||||||
|
|
||||||
|
return new int[]{result};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int executeBatchInternal() throws SQLException {
|
||||||
|
|
||||||
|
if (!isAddBatch) {
|
||||||
|
addCurrentRowParamToList(); // add current param to batch list
|
||||||
|
}
|
||||||
|
|
||||||
|
//1. generate batch sql
|
||||||
|
String sql = generateExecuteSql();
|
||||||
|
//2. execute batch sql
|
||||||
|
int result = executeSql(sql);
|
||||||
|
|
||||||
|
//3. clear batch param list
|
||||||
|
this.sqlParamList.clear();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate the batch sql
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String generateExecuteSql() {
|
||||||
|
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
stringBuilder.append(prefix);
|
||||||
|
stringBuilder.append(" into ");
|
||||||
|
|
||||||
|
if (!isTableNameDynamic) {
|
||||||
|
// tablename will not need to be replaced
|
||||||
|
String middleValue = replaceMiddleListParam(middle, sqlParamList);
|
||||||
|
stringBuilder.append(middleValue);
|
||||||
|
stringBuilder.append(" values");
|
||||||
|
|
||||||
|
stringBuilder.append(replaceValueListParam(valueList, sqlParamList));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// need to replace tablename
|
||||||
|
|
||||||
|
if (sqlParamList.size() > 0) {
|
||||||
|
|
||||||
|
TSDBPreparedParam firstPreparedParam = sqlParamList.get(0);
|
||||||
|
|
||||||
|
//replace middle part and value part of first row
|
||||||
|
String firstRow = replaceMiddleAndValuePart(firstPreparedParam);
|
||||||
|
stringBuilder.append(firstRow);
|
||||||
|
|
||||||
|
//the first param in the middleParamList is the tableName
|
||||||
|
String lastTableName = firstPreparedParam.getMiddleParamList().get(0).toString();
|
||||||
|
|
||||||
|
if (sqlParamList.size() > 1) {
|
||||||
|
|
||||||
|
for (int i = 1; i < sqlParamList.size(); i++) {
|
||||||
|
TSDBPreparedParam currentParam = sqlParamList.get(i);
|
||||||
|
String currentTableName = currentParam.getMiddleParamList().get(0).toString();
|
||||||
|
if (lastTableName.equalsIgnoreCase(currentTableName)) {
|
||||||
|
// tablename is same with the last row ,so only need to append the part of value
|
||||||
|
|
||||||
|
String values = replaceTemplateParam(valueList, currentParam.getValueList());
|
||||||
|
stringBuilder.append(values);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// tablename difference with the last row
|
||||||
|
//need to replace middle part and value part
|
||||||
|
String row = replaceMiddleAndValuePart(currentParam);
|
||||||
|
stringBuilder.append(row);
|
||||||
|
lastTableName = currentTableName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
stringBuilder.append(middle);
|
||||||
|
stringBuilder.append(" values");
|
||||||
|
stringBuilder.append(valueList);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replace the middle and value part
|
||||||
|
*
|
||||||
|
* @param tsdbPreparedParam
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String replaceMiddleAndValuePart(TSDBPreparedParam tsdbPreparedParam) {
|
||||||
|
|
||||||
|
StringBuilder stringBuilder = new StringBuilder(" ");
|
||||||
|
|
||||||
|
String middlePart = replaceTemplateParam(middle, tsdbPreparedParam.getMiddleParamList());
|
||||||
|
|
||||||
|
stringBuilder.append(middlePart);
|
||||||
|
stringBuilder.append(" values ");
|
||||||
|
|
||||||
|
String valuePart = replaceTemplateParam(valueList, tsdbPreparedParam.getValueList());
|
||||||
|
stringBuilder.append(valuePart);
|
||||||
|
stringBuilder.append(" ");
|
||||||
|
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replace the placeholder of the middle part of sql template with TSDBPreparedParam list
|
||||||
|
*
|
||||||
|
* @param template
|
||||||
|
* @param sqlParamList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String replaceMiddleListParam(String template, List<TSDBPreparedParam> sqlParamList) {
|
||||||
|
|
||||||
|
if (sqlParamList.size() > 0) {
|
||||||
|
|
||||||
|
//becase once the subTableName is static then will be ignore the tag which after the first setTag
|
||||||
|
return replaceTemplateParam(template, sqlParamList.get(0).getMiddleParamList());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replace the placeholder of the template with TSDBPreparedParam list
|
||||||
|
*
|
||||||
|
* @param template
|
||||||
|
* @param sqlParamList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String replaceValueListParam(String template, List<TSDBPreparedParam> sqlParamList) {
|
||||||
|
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
if (sqlParamList.size() > 0) {
|
||||||
|
|
||||||
|
for (TSDBPreparedParam tsdbPreparedParam : sqlParamList) {
|
||||||
|
|
||||||
|
String tmp = replaceTemplateParam(template, tsdbPreparedParam.getValueList());
|
||||||
|
|
||||||
|
stringBuilder.append(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
stringBuilder.append(template);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replace the placeholder of the template with paramList
|
||||||
|
*
|
||||||
|
* @param template
|
||||||
|
* @param paramList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String replaceTemplateParam(String template, List<Object> paramList) {
|
||||||
|
|
||||||
|
if (paramList.size() > 0) {
|
||||||
|
|
||||||
|
String tmp = template;
|
||||||
|
|
||||||
|
for (int i = 0; i < paramList.size(); ++i) {
|
||||||
|
|
||||||
|
String paraStr = getParamString(paramList.get(i));
|
||||||
|
|
||||||
|
tmp = tmp.replaceFirst("[" + PLACEHOLDER + "]", paraStr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the string of param object
|
||||||
|
*
|
||||||
|
* @param paramObj
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getParamString(Object paramObj) {
|
||||||
|
|
||||||
|
String paraStr = paramObj.toString();
|
||||||
|
if (paramObj instanceof Timestamp || (paramObj instanceof String && !DEFAULT_VALUE.equalsIgnoreCase(paraStr))) {
|
||||||
|
paraStr = "'" + paraStr + "'";
|
||||||
|
}
|
||||||
|
return paraStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int executeSql(String sql) throws SQLException {
|
||||||
|
|
||||||
|
return tsdbPreparedStatement.executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,352 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.sql.Array;
|
||||||
|
import java.sql.Blob;
|
||||||
|
import java.sql.CallableStatement;
|
||||||
|
import java.sql.Clob;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.NClob;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLClientInfoException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.SQLWarning;
|
||||||
|
import java.sql.SQLXML;
|
||||||
|
import java.sql.Savepoint;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.Struct;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
public class TSDBConnection implements Connection {
|
||||||
|
|
||||||
|
private TSDBJNIConnector connector = null;
|
||||||
|
|
||||||
|
protected Properties props = null;
|
||||||
|
|
||||||
|
private String catalog = null;
|
||||||
|
|
||||||
|
private TSDBDatabaseMetaData dbMetaData = null;
|
||||||
|
|
||||||
|
private Properties clientInfoProps = new Properties();
|
||||||
|
|
||||||
|
private int timeoutMilliseconds = 0;
|
||||||
|
|
||||||
|
private String tsCharSet = "";
|
||||||
|
|
||||||
|
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
|
||||||
|
this.dbMetaData = meta;
|
||||||
|
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
|
||||||
|
Integer.parseInt(info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "0")),
|
||||||
|
info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME), info.getProperty(TSDBDriver.PROPERTY_KEY_USER),
|
||||||
|
info.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void connect(String host, int port, String dbName, String user, String password) throws SQLException {
|
||||||
|
this.connector = new TSDBJNIConnector();
|
||||||
|
this.connector.connect(host, port, dbName, user, password);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.setCatalog(dbName);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dbMetaData.setConnection(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TSDBJNIConnector getConnection() {
|
||||||
|
return this.connector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement createStatement() throws SQLException {
|
||||||
|
if (!this.connector.isClosed()) {
|
||||||
|
return new TSDBStatement(this.connector);
|
||||||
|
} else {
|
||||||
|
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
||||||
|
if (!this.connector.isClosed()) {
|
||||||
|
return new TSDBPreparedStatement(this.connector, sql);
|
||||||
|
} else {
|
||||||
|
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CallableStatement prepareCall(String sql) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String nativeSQL(String sql) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoCommit(boolean autoCommit) throws SQLException {
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getAutoCommit() throws SQLException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void commit() throws SQLException {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rollback() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws SQLException {
|
||||||
|
if (this.connector != null && !this.connector.isClosed()) {
|
||||||
|
this.connector.closeConnection();
|
||||||
|
} else {
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg("connection is already closed!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isClosed() throws SQLException {
|
||||||
|
return this.connector.isClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A connection's database is able to provide information describing its tables,
|
||||||
|
* its supported SQL grammar, its stored procedures, the capabilities of this
|
||||||
|
* connection, etc. This information is made available through a
|
||||||
|
* DatabaseMetaData object.
|
||||||
|
*
|
||||||
|
* @return a DatabaseMetaData object for this connection
|
||||||
|
* @exception SQLException
|
||||||
|
* if a database access error occurs
|
||||||
|
*/
|
||||||
|
public DatabaseMetaData getMetaData() throws SQLException {
|
||||||
|
return this.dbMetaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This readOnly option is not supported by TDengine. However, the method is intentionally left blank here to
|
||||||
|
* support HikariCP connection.
|
||||||
|
* @param readOnly
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public void setReadOnly(boolean readOnly) throws SQLException {
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReadOnly() throws SQLException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCatalog(String catalog) throws SQLException {
|
||||||
|
this.catalog = catalog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCatalog() throws SQLException {
|
||||||
|
return this.catalog;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The transaction isolation level option is not supported by TDengine.
|
||||||
|
* This method is intentionally left empty to support HikariCP connection.
|
||||||
|
* @param level
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public void setTransactionIsolation(int level) throws SQLException {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The transaction isolation level option is not supported by TDengine.
|
||||||
|
* @return
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public int getTransactionIsolation() throws SQLException {
|
||||||
|
return Connection.TRANSACTION_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SQLWarning getWarnings() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearWarnings() throws SQLException {
|
||||||
|
// left blank to support HikariCP connection
|
||||||
|
//todo: implement getWarnings according to the warning messages returned from TDengine
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
|
||||||
|
throws SQLException {
|
||||||
|
// This method is implemented in the current way to support Spark
|
||||||
|
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) {
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY) {
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.prepareStatement(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Class<?>> getTypeMap() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHoldability(int holdability) throws SQLException {
|
||||||
|
// intentionally left empty to support druid connection pool.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the transaction is not supported by TDengine, so the opened ResultSet Objects will remain open
|
||||||
|
* @return
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public int getHoldability() throws SQLException {
|
||||||
|
//intentionally left empty to support HikariCP connection.
|
||||||
|
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Savepoint setSavepoint() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Savepoint setSavepoint(String name) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rollback(Savepoint savepoint) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
|
||||||
|
throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
|
||||||
|
int resultSetHoldability) throws SQLException {
|
||||||
|
return this.prepareStatement(sql, resultSetType, resultSetConcurrency);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
|
||||||
|
int resultSetHoldability) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Clob createClob() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Blob createBlob() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NClob createNClob() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SQLXML createSQLXML() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid(int timeout) throws SQLException {
|
||||||
|
return !this.isClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientInfo(String name, String value) throws SQLClientInfoException {
|
||||||
|
clientInfoProps.setProperty(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientInfo(Properties properties) throws SQLClientInfoException {
|
||||||
|
for (Enumeration<Object> enumer = properties.keys(); enumer.hasMoreElements();) {
|
||||||
|
String name = (String) enumer.nextElement();
|
||||||
|
clientInfoProps.put(name, properties.getProperty(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientInfo(String name) throws SQLException {
|
||||||
|
return clientInfoProps.getProperty(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Properties getClientInfo() throws SQLException {
|
||||||
|
return clientInfoProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSchema(String schema) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSchema() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void abort(Executor executor) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
|
||||||
|
this.timeoutMilliseconds = milliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNetworkTimeout() throws SQLException {
|
||||||
|
return this.timeoutMilliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
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<Integer, String> DATATYPE_MAP = null;
|
||||||
|
|
||||||
|
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 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<Integer, String>();
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,800 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
|
||||||
|
|
||||||
|
private String dbProductName = null;
|
||||||
|
private String url = null;
|
||||||
|
private String userName = null;
|
||||||
|
private Connection conn = null;
|
||||||
|
|
||||||
|
public TSDBDatabaseMetaData(String dbProductName, String url, String userName) {
|
||||||
|
this.dbProductName = dbProductName;
|
||||||
|
this.url = url;
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConnection(Connection conn) {
|
||||||
|
this.conn = conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean allProceduresAreCallable() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean allTablesAreSelectable() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getURL() throws SQLException {
|
||||||
|
return this.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName() throws SQLException {
|
||||||
|
return this.userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReadOnly() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nullsAreSortedHigh() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nullsAreSortedLow() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nullsAreSortedAtStart() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nullsAreSortedAtEnd() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabaseProductName() throws SQLException {
|
||||||
|
return this.dbProductName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabaseProductVersion() throws SQLException {
|
||||||
|
return "1.5.1";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDriverName() throws SQLException {
|
||||||
|
return TSDBDriver.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDriverVersion() throws SQLException {
|
||||||
|
return "1.0.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDriverMajorVersion() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDriverMinorVersion() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
|
||||||
|
throws SQLException {
|
||||||
|
if (conn != null && !conn.isClosed()) {
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
if (catalog == null || catalog.length() < 1) {
|
||||||
|
catalog = conn.getCatalog();
|
||||||
|
}
|
||||||
|
stmt.executeUpdate("use " + catalog);
|
||||||
|
ResultSet resultSet0 = stmt.executeQuery("show tables");
|
||||||
|
GetTablesResultSet getTablesResultSet = new GetTablesResultSet(resultSet0, catalog, schemaPattern, tableNamePattern, types);
|
||||||
|
return getTablesResultSet;
|
||||||
|
} else {
|
||||||
|
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getSchemas() throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getCatalogs() throws SQLException {
|
||||||
|
|
||||||
|
if (conn != null && !conn.isClosed()) {
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
ResultSet resultSet0 = stmt.executeQuery("show databases");
|
||||||
|
CatalogResultSet resultSet = new CatalogResultSet(resultSet0);
|
||||||
|
return resultSet;
|
||||||
|
} else {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getTableTypes() throws SQLException {
|
||||||
|
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
|
||||||
|
|
||||||
|
// set up ColumnMetaDataList
|
||||||
|
List<ColumnMetaData> columnMetaDataList = new ArrayList<ColumnMetaData>(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<TSDBResultSetRowData> rowDataList = new ArrayList<TSDBResultSetRowData>(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 ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
|
||||||
|
throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,358 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Java SQL framework allows for multiple database drivers. Each driver
|
||||||
|
* should supply a class that implements the Driver interface
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The DriverManager will try to load as many drivers as it can find and then
|
||||||
|
* for any given connection request, it will ask each driver in turn to try to
|
||||||
|
* connect to the target URL.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It is strongly recommended that each Driver class should be small and stand
|
||||||
|
* alone so that the Driver class can be loaded and queried without bringing in
|
||||||
|
* vast quantities of supporting code.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* When a Driver class is loaded, it should create an instance of itself and
|
||||||
|
* register it with the DriverManager. This means that a user can load and
|
||||||
|
* register a driver by doing Class.forName("foo.bah.Driver")
|
||||||
|
*/
|
||||||
|
public class TSDBDriver implements java.sql.Driver {
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
private static final String URL_PREFIX1 = "jdbc:TSDB://";
|
||||||
|
|
||||||
|
private static final String URL_PREFIX = "jdbc:TAOS://";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key used to retrieve the database value from the properties instance passed
|
||||||
|
* to the driver.
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_KEY_DBNAME = "dbname";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key used to retrieve the host value from the properties instance passed to
|
||||||
|
* the driver.
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_KEY_HOST = "host";
|
||||||
|
/**
|
||||||
|
* Key used to retrieve the password value from the properties instance passed
|
||||||
|
* to the driver.
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_KEY_PASSWORD = "password";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key used to retrieve the port number value from the properties instance
|
||||||
|
* passed to the driver.
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_KEY_PORT = "port";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key used to retrieve the user value from the properties instance passed to
|
||||||
|
* the driver.
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_KEY_USER = "user";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key for the configuration file directory of TSDB client in properties instance
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_KEY_CONFIG_DIR = "cfgdir";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key for the timezone used by the TSDB client in properties instance
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_KEY_TIME_ZONE = "timezone";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key for the locale used by the TSDB client in properties instance
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_KEY_LOCALE = "locale";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key for the char encoding used by the TSDB client in properties instance
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_KEY_CHARSET = "charset";
|
||||||
|
|
||||||
|
public static final String PROPERTY_KEY_PROTOCOL = "protocol";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index for port coming out of parseHostPortPair().
|
||||||
|
*/
|
||||||
|
public final static int PORT_NUMBER_INDEX = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index for host coming out of parseHostPortPair().
|
||||||
|
*/
|
||||||
|
public final static int HOST_NAME_INDEX = 0;
|
||||||
|
|
||||||
|
private TSDBDatabaseMetaData dbMetaData = null;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
java.sql.DriverManager.registerDriver(new TSDBDriver());
|
||||||
|
} catch (SQLException E) {
|
||||||
|
throw new RuntimeException(TSDBConstants.WrapErrMsg("can't register tdengine jdbc driver!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection connect(String url, Properties info) throws SQLException {
|
||||||
|
if (url == null) {
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg("url is not set!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Properties props = null;
|
||||||
|
|
||||||
|
if ((props = parseURL(url, info)) == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR), (String) props.get(PROPERTY_KEY_LOCALE), (String) props.get(PROPERTY_KEY_CHARSET),
|
||||||
|
(String) props.get(PROPERTY_KEY_TIME_ZONE));
|
||||||
|
Connection newConn = new TSDBConnection(props, this.dbMetaData);
|
||||||
|
return newConn;
|
||||||
|
} catch (SQLWarning sqlWarning) {
|
||||||
|
sqlWarning.printStackTrace();
|
||||||
|
Connection newConn = new TSDBConnection(props, this.dbMetaData);
|
||||||
|
return newConn;
|
||||||
|
} catch (SQLException sqlEx) {
|
||||||
|
throw sqlEx;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
SQLException sqlEx = new SQLException("SQLException:" + ex.toString());
|
||||||
|
sqlEx.initCause(ex);
|
||||||
|
throw sqlEx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses hostPortPair in the form of [host][:port] into an array, with the
|
||||||
|
* element of index HOST_NAME_INDEX being the host (or null if not specified),
|
||||||
|
* and the element of index PORT_NUMBER_INDEX being the port (or null if not
|
||||||
|
* specified).
|
||||||
|
*
|
||||||
|
* @param hostPortPair
|
||||||
|
* host and port in form of of [host][:port]
|
||||||
|
*
|
||||||
|
* @return array containing host and port as Strings
|
||||||
|
*
|
||||||
|
* @throws SQLException
|
||||||
|
* if a parse error occurs
|
||||||
|
*/
|
||||||
|
protected static String[] parseHostPortPair(String hostPortPair) throws SQLException {
|
||||||
|
String[] splitValues = new String[2];
|
||||||
|
|
||||||
|
int portIndex = hostPortPair.indexOf(":");
|
||||||
|
|
||||||
|
String hostname = null;
|
||||||
|
|
||||||
|
if (portIndex != -1) {
|
||||||
|
if ((portIndex + 1) < hostPortPair.length()) {
|
||||||
|
String portAsString = hostPortPair.substring(portIndex + 1);
|
||||||
|
hostname = hostPortPair.substring(0, portIndex);
|
||||||
|
|
||||||
|
splitValues[HOST_NAME_INDEX] = hostname;
|
||||||
|
|
||||||
|
splitValues[PORT_NUMBER_INDEX] = portAsString;
|
||||||
|
} else {
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg("port is not proper!"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
splitValues[HOST_NAME_INDEX] = hostPortPair;
|
||||||
|
splitValues[PORT_NUMBER_INDEX] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return splitValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean acceptsURL(String url) throws SQLException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
|
||||||
|
if (info == null) {
|
||||||
|
info = new Properties();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((url != null) && (url.startsWith(URL_PREFIX) || url.startsWith(URL_PREFIX1))) {
|
||||||
|
info = parseURL(url, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
DriverPropertyInfo hostProp = new DriverPropertyInfo(PROPERTY_KEY_HOST, info.getProperty(PROPERTY_KEY_HOST));
|
||||||
|
hostProp.required = true;
|
||||||
|
|
||||||
|
DriverPropertyInfo portProp = new DriverPropertyInfo(PROPERTY_KEY_PORT,
|
||||||
|
info.getProperty(PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT));
|
||||||
|
portProp.required = false;
|
||||||
|
|
||||||
|
DriverPropertyInfo dbProp = new DriverPropertyInfo(PROPERTY_KEY_DBNAME, info.getProperty(PROPERTY_KEY_DBNAME));
|
||||||
|
dbProp.required = false;
|
||||||
|
dbProp.description = "Database name";
|
||||||
|
|
||||||
|
DriverPropertyInfo userProp = new DriverPropertyInfo(PROPERTY_KEY_USER, info.getProperty(PROPERTY_KEY_USER));
|
||||||
|
userProp.required = true;
|
||||||
|
|
||||||
|
DriverPropertyInfo passwordProp = new DriverPropertyInfo(PROPERTY_KEY_PASSWORD,
|
||||||
|
info.getProperty(PROPERTY_KEY_PASSWORD));
|
||||||
|
passwordProp.required = true;
|
||||||
|
|
||||||
|
DriverPropertyInfo[] propertyInfo = new DriverPropertyInfo[5];
|
||||||
|
propertyInfo[0] = hostProp;
|
||||||
|
propertyInfo[1] = portProp;
|
||||||
|
propertyInfo[2] = dbProp;
|
||||||
|
propertyInfo[3] = userProp;
|
||||||
|
propertyInfo[4] = passwordProp;
|
||||||
|
|
||||||
|
return propertyInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* example: jdbc:TSDB://127.0.0.1:0/db?user=root&password=your_password
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Properties parseURL(String url, Properties defaults) throws java.sql.SQLException {
|
||||||
|
Properties urlProps = (defaults != null) ? defaults : new Properties();
|
||||||
|
if (url == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.startsWithIgnoreCase(url, URL_PREFIX) && !StringUtils.startsWithIgnoreCase(url, URL_PREFIX1)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String urlForMeta = url;
|
||||||
|
|
||||||
|
String dbProductName = url.substring(url.indexOf(":") + 1);
|
||||||
|
dbProductName = dbProductName.substring(0, dbProductName.indexOf(":"));
|
||||||
|
int beginningOfSlashes = url.indexOf("//");
|
||||||
|
url = url.substring(beginningOfSlashes + 2);
|
||||||
|
|
||||||
|
String host = url.substring(0, url.indexOf(":"));
|
||||||
|
url = url.substring(url.indexOf(":") + 1);
|
||||||
|
urlProps.setProperty(PROPERTY_KEY_HOST, host);
|
||||||
|
|
||||||
|
String port = url.substring(0, url.indexOf("/"));
|
||||||
|
urlProps.setProperty(PROPERTY_KEY_PORT, port);
|
||||||
|
url = url.substring(url.indexOf("/") + 1);
|
||||||
|
|
||||||
|
if (url.indexOf("?") != -1) {
|
||||||
|
String dbName = url.substring(0, url.indexOf("?"));
|
||||||
|
urlProps.setProperty(PROPERTY_KEY_DBNAME, dbName);
|
||||||
|
url = url.trim().substring(1);
|
||||||
|
} else {
|
||||||
|
// without user & password so return
|
||||||
|
String dbName = url.trim();
|
||||||
|
urlProps.setProperty(PROPERTY_KEY_DBNAME, dbName);
|
||||||
|
this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, urlProps.getProperty("user"));
|
||||||
|
return urlProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] queryStrings = url.trim().split("&");
|
||||||
|
String user = "";
|
||||||
|
for (String queryStr : queryStrings) {
|
||||||
|
String[] kvPair = queryStr.trim().split("=");
|
||||||
|
if (kvPair.length < 2){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (kvPair[0].toLowerCase()) {
|
||||||
|
case PROPERTY_KEY_USER:
|
||||||
|
urlProps.setProperty(PROPERTY_KEY_USER, kvPair[1]);
|
||||||
|
user = kvPair[1];
|
||||||
|
break;
|
||||||
|
case PROPERTY_KEY_PASSWORD:
|
||||||
|
urlProps.setProperty(PROPERTY_KEY_PASSWORD, kvPair[1]);
|
||||||
|
break;
|
||||||
|
case PROPERTY_KEY_TIME_ZONE:
|
||||||
|
urlProps.setProperty(PROPERTY_KEY_TIME_ZONE, kvPair[1]);
|
||||||
|
break;
|
||||||
|
case PROPERTY_KEY_LOCALE:
|
||||||
|
urlProps.setProperty(PROPERTY_KEY_LOCALE, kvPair[1]);
|
||||||
|
break;
|
||||||
|
case PROPERTY_KEY_CHARSET:
|
||||||
|
urlProps.setProperty(PROPERTY_KEY_CHARSET, kvPair[1]);
|
||||||
|
break;
|
||||||
|
case PROPERTY_KEY_CONFIG_DIR:
|
||||||
|
urlProps.setProperty(PROPERTY_KEY_CONFIG_DIR, kvPair[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, user);
|
||||||
|
|
||||||
|
return urlProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMajorVersion() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinorVersion() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean jdbcCompliant() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the host property
|
||||||
|
*
|
||||||
|
* @param props
|
||||||
|
* the java.util.Properties instance to retrieve the hostname from.
|
||||||
|
*
|
||||||
|
* @return the host
|
||||||
|
*/
|
||||||
|
public String host(Properties props) {
|
||||||
|
return props.getProperty(PROPERTY_KEY_HOST, "localhost");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the port number property
|
||||||
|
*
|
||||||
|
* @param props
|
||||||
|
* the properties to get the port number from
|
||||||
|
*
|
||||||
|
* @return the port number
|
||||||
|
*/
|
||||||
|
public int port(Properties props) {
|
||||||
|
return Integer.parseInt(props.getProperty(PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the database property from <code>props</code>
|
||||||
|
*
|
||||||
|
* @param props
|
||||||
|
* the Properties to look for the database property.
|
||||||
|
*
|
||||||
|
* @return the database name.
|
||||||
|
*/
|
||||||
|
public String database(Properties props) {
|
||||||
|
return props.getProperty(PROPERTY_KEY_DBNAME);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,223 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* TDengine error code and error message enumeration.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum TSDBError {
|
||||||
|
|
||||||
|
TSDB_CODE_SUCCESS(0, "success"),
|
||||||
|
TSDB_CODE_ACTION_IN_PROGRESS(1, "in progress"),
|
||||||
|
TSDB_CODE_LAST_SESSION_NOT_FINISHED(5, "last session not finished"),
|
||||||
|
TSDB_CODE_INVALID_SESSION_ID(6, "invalid session ID"),
|
||||||
|
TSDB_CODE_INVALID_TRAN_ID(7, "invalid tran ID"),
|
||||||
|
TSDB_CODE_INVALID_MSG_TYPE(8, "invalid msg type"),
|
||||||
|
TSDB_CODE_ALREADY_PROCESSED(9, "alredy processed"),
|
||||||
|
TSDB_CODE_AUTH_FAILURE(10, "authentication failure"),
|
||||||
|
TSDB_CODE_WRONG_MSG_SIZE(11, "wrong msg size"),
|
||||||
|
TSDB_CODE_UNEXPECTED_RESPONSE(12, "unexpected response"),
|
||||||
|
TSDB_CODE_INVALID_RESPONSE_TYPE(13, "invalid response type"),
|
||||||
|
TSDB_CODE_NO_RESOURCE(14, "no resource"),
|
||||||
|
TSDB_CODE_INVALID_TIME_STAMP(15, "invalid time stamp"),
|
||||||
|
TSDB_CODE_MISMATCHED_METER_ID(16, "mismatched meter ID"),
|
||||||
|
TSDB_CODE_ACTION_TRANS_NOT_FINISHED(17, "transcation not finished"),
|
||||||
|
TSDB_CODE_ACTION_NOT_ONLINE(18, "not online"),
|
||||||
|
TSDB_CODE_ACTION_SEND_FAILD(19, "send failed"),
|
||||||
|
TSDB_CODE_NOT_ACTIVE_SESSION(20, "not active session"),
|
||||||
|
TSDB_CODE_INSERT_FAILED(21, "insert failed"),
|
||||||
|
TSDB_CODE_APP_ERROR(22, "App error"),
|
||||||
|
TSDB_CODE_INVALID_IE(23, "invalid IE"),
|
||||||
|
TSDB_CODE_INVALID_VALUE(24, "invalid value"),
|
||||||
|
TSDB_CODE_REDIRECT(25, "service not available"),
|
||||||
|
TSDB_CODE_ALREADY_THERE(26, "already there"),
|
||||||
|
TSDB_CODE_INVALID_METER_ID(27, "invalid meter ID"),
|
||||||
|
TSDB_CODE_INVALID_SQL(28, "invalid SQL"), // this message often comes with additional info which will vary based on the specific error situation
|
||||||
|
TSDB_CODE_NETWORK_UNAVAIL(29, "failed to connect to server"),
|
||||||
|
TSDB_CODE_INVALID_MSG_LEN(30, "invalid msg len"),
|
||||||
|
TSDB_CODE_INVALID_DB(31, "invalid DB"),
|
||||||
|
TSDB_CODE_INVALID_TABLE(32, "invalid table"),
|
||||||
|
TSDB_CODE_DB_ALREADY_EXIST(33, "DB already there"),
|
||||||
|
TSDB_CODE_TABLE_ALREADY_EXIST(34, "table already there"),
|
||||||
|
TSDB_CODE_INVALID_USER(35, "invalid user name"),
|
||||||
|
TSDB_CODE_INVALID_ACCT(36, "invalid acct name"),
|
||||||
|
TSDB_CODE_INVALID_PASS(37, "invalid password"),
|
||||||
|
TSDB_CODE_DB_NOT_SELECTED(38, "DB not selected"),
|
||||||
|
TSDB_CODE_MEMORY_CORRUPTED(39, "memory corrupted"),
|
||||||
|
TSDB_CODE_USER_ALREADY_EXIST(40, "user name exists"),
|
||||||
|
TSDB_CODE_NO_RIGHTS(41, "not authorized"),
|
||||||
|
TSDB_CODE_DISCONNECTED(42, "login disconnected), login again"),
|
||||||
|
TSDB_CODE_NO_MASTER(43, "mgmt master node not available"),
|
||||||
|
TSDB_CODE_NOT_CONFIGURED(44, "not configured"),
|
||||||
|
TSDB_CODE_INVALID_OPTION(45, "invalid option"),
|
||||||
|
TSDB_CODE_NODE_OFFLINE(46, "node offline"),
|
||||||
|
TSDB_CODE_SYNC_REQUIRED(47, "sync required"),
|
||||||
|
TSDB_CODE_NO_ENOUGH_DNODES(48, "more dnodes are needed"),
|
||||||
|
TSDB_CODE_UNSYNCED(49, "node in unsynced state"),
|
||||||
|
TSDB_CODE_TOO_SLOW(50, "too slow"),
|
||||||
|
TSDB_CODE_OTHERS(51, "others"),
|
||||||
|
TSDB_CODE_NO_REMOVE_MASTER(52, "can't remove dnode which is master"),
|
||||||
|
TSDB_CODE_WRONG_SCHEMA(53, "wrong schema"),
|
||||||
|
TSDB_CODE_NO_RESULT(54, "no results"),
|
||||||
|
TSDB_CODE_TOO_MANY_USERS(55, "num of users execeed maxUsers"),
|
||||||
|
TSDB_CODE_TOO_MANY_DATABSES(56, "num of databases execeed maxDbs"),
|
||||||
|
TSDB_CODE_TOO_MANY_TABLES(57, "num of tables execeed maxTables"),
|
||||||
|
TSDB_CODE_TOO_MANY_DNODES(58, "num of dnodes execeed maxDnodes"),
|
||||||
|
TSDB_CODE_TOO_MANY_ACCTS(59, "num of accounts execeed maxAccts"),
|
||||||
|
TSDB_CODE_ACCT_ALREADY_EXIST(60, "accout name exists"),
|
||||||
|
TSDB_CODE_DNODE_ALREADY_EXIST(61, "dnode ip exists"),
|
||||||
|
TSDB_CODE_SDB_ERROR(62, "sdb error"),
|
||||||
|
TSDB_CODE_METRICMETA_EXPIRED(63, "metric meta expired"), // local cached metric-meta expired causes error in metric query
|
||||||
|
TSDB_CODE_NOT_READY(64, "not ready"), // peer is not ready to process data
|
||||||
|
TSDB_CODE_MAX_SESSIONS(65, "too many sessions on server"), // too many sessions
|
||||||
|
TSDB_CODE_MAX_CONNECTIONS(66, "too many sessions from app"), // too many connections
|
||||||
|
TSDB_CODE_SESSION_ALREADY_EXIST(67, "session to dest is already there"),
|
||||||
|
TSDB_CODE_NO_QSUMMARY(68, "query list not there), please show again"),
|
||||||
|
TSDB_CODE_SERV_OUT_OF_MEMORY(69, "server out of memory"),
|
||||||
|
TSDB_CODE_INVALID_QHANDLE(70, "invalid query handle"),
|
||||||
|
TSDB_CODE_RELATED_TABLES_EXIST(71, "tables related to metric exist"),
|
||||||
|
TSDB_CODE_MONITOR_DB_FORBEIDDEN(72, "can't drop monitor database or tables"),
|
||||||
|
TSDB_CODE_VG_COMMITLOG_INIT_FAILED(73, "commit log init failed"),
|
||||||
|
TSDB_CODE_VG_INIT_FAILED(74, "vgroup init failed"),
|
||||||
|
TSDB_CODE_DATA_ALREADY_IMPORTED(75, "data is already imported"),
|
||||||
|
TSDB_CODE_OPS_NOT_SUPPORT(76, "not supported operation"),
|
||||||
|
TSDB_CODE_INVALID_QUERY_ID(77, "invalid query id string"),
|
||||||
|
TSDB_CODE_INVALID_STREAM_ID(78, "invalid stream id string"),
|
||||||
|
TSDB_CODE_INVALID_CONNECTION(79, "invalid connection string"),
|
||||||
|
TSDB_CODE_ACTION_NOT_BALANCED(80, "dnode not balanced"),
|
||||||
|
TSDB_CODE_CLI_OUT_OF_MEMORY(81, "client out of memory"),
|
||||||
|
TSDB_CODE_DATA_OVERFLOW(82, "data value overflow"),
|
||||||
|
TSDB_CODE_QUERY_CANCELLED(83, "query cancelled"),
|
||||||
|
TSDB_CODE_GRANT_POINT_LIMITED(84, "grant points limited"),
|
||||||
|
TSDB_CODE_GRANT_EXPIRED(85, "grant expired"),
|
||||||
|
TSDB_CODE_CLI_NO_DISKSPACE(86, "client no disk space"),
|
||||||
|
TSDB_CODE_FILE_CORRUPTED(87, "DB file corrupted"),
|
||||||
|
TSDB_CODE_INVALID_CLIENT_VERSION(88, "version of client and server not match");
|
||||||
|
|
||||||
|
private long errCode;
|
||||||
|
private String errMessage;
|
||||||
|
private static Map<Integer, String> errorCodeMap = new HashMap<>(86);
|
||||||
|
static {
|
||||||
|
errorCodeMap.put(0, "success");
|
||||||
|
errorCodeMap.put(1, "in progress");
|
||||||
|
errorCodeMap.put(5, "last session not finished");
|
||||||
|
errorCodeMap.put(6, "invalid session ID");
|
||||||
|
errorCodeMap.put(7, "invalid tran ID");
|
||||||
|
errorCodeMap.put(8, "invalid msg type");
|
||||||
|
errorCodeMap.put(9, "alredy processed");
|
||||||
|
errorCodeMap.put(10, "authentication failure");
|
||||||
|
errorCodeMap.put(11, "wrong msg size");
|
||||||
|
errorCodeMap.put(12, "unexpected response");
|
||||||
|
errorCodeMap.put(13, "invalid response type");
|
||||||
|
errorCodeMap.put(14, "no resource");
|
||||||
|
errorCodeMap.put(15, "invalid time stamp");
|
||||||
|
errorCodeMap.put(16, "mismatched meter ID");
|
||||||
|
errorCodeMap.put(17, "transcation not finished");
|
||||||
|
errorCodeMap.put(18, "not online");
|
||||||
|
errorCodeMap.put(19, "send failed");
|
||||||
|
errorCodeMap.put(20, "not active session");
|
||||||
|
errorCodeMap.put(21, "insert failed");
|
||||||
|
errorCodeMap.put(22, "App error");
|
||||||
|
errorCodeMap.put(23, "invalid IE");
|
||||||
|
errorCodeMap.put(24, "invalid value");
|
||||||
|
errorCodeMap.put(25, "service not available");
|
||||||
|
errorCodeMap.put(26, "already there");
|
||||||
|
errorCodeMap.put(27, "invalid meter ID");
|
||||||
|
errorCodeMap.put(28, "invalid SQL"); // this message often comes with additional info which will vary based on the specific error situation
|
||||||
|
errorCodeMap.put(29, "failed to connect to server");
|
||||||
|
errorCodeMap.put(30, "invalid msg len");
|
||||||
|
errorCodeMap.put(31, "invalid DB");
|
||||||
|
errorCodeMap.put(32, "invalid table");
|
||||||
|
errorCodeMap.put(33, "DB already there");
|
||||||
|
errorCodeMap.put(34, "table already there");
|
||||||
|
errorCodeMap.put(35, "invalid user name");
|
||||||
|
errorCodeMap.put(36, "invalid acct name");
|
||||||
|
errorCodeMap.put(37, "invalid password");
|
||||||
|
errorCodeMap.put(38, "DB not selected");
|
||||||
|
errorCodeMap.put(39, "memory corrupted");
|
||||||
|
errorCodeMap.put(40, "user name exists");
|
||||||
|
errorCodeMap.put(41, "not authorized");
|
||||||
|
errorCodeMap.put(42, "login disconnected); login again");
|
||||||
|
errorCodeMap.put(43, "mgmt master node not available");
|
||||||
|
errorCodeMap.put(44, "not configured");
|
||||||
|
errorCodeMap.put(45, "invalid option");
|
||||||
|
errorCodeMap.put(46, "node offline");
|
||||||
|
errorCodeMap.put(47, "sync required");
|
||||||
|
errorCodeMap.put(48, "more dnodes are needed");
|
||||||
|
errorCodeMap.put(49, "node in unsynced state");
|
||||||
|
errorCodeMap.put(50, "too slow");
|
||||||
|
errorCodeMap.put(51, "others");
|
||||||
|
errorCodeMap.put(52, "can't remove dnode which is master");
|
||||||
|
errorCodeMap.put(53, "wrong schema");
|
||||||
|
errorCodeMap.put(54, "no results");
|
||||||
|
errorCodeMap.put(55, "num of users execeed maxUsers");
|
||||||
|
errorCodeMap.put(56, "num of databases execeed maxDbs");
|
||||||
|
errorCodeMap.put(57, "num of tables execeed maxTables");
|
||||||
|
errorCodeMap.put(58, "num of dnodes execeed maxDnodes");
|
||||||
|
errorCodeMap.put(59, "num of accounts execeed maxAccts");
|
||||||
|
errorCodeMap.put(60, "accout name exists");
|
||||||
|
errorCodeMap.put(61, "dnode ip exists");
|
||||||
|
errorCodeMap.put(62, "sdb error");
|
||||||
|
errorCodeMap.put(63, "metric meta expired"); // local cached metric-meta expired causes error in metric query
|
||||||
|
errorCodeMap.put(64, "not ready"); // peer is not ready to process data
|
||||||
|
errorCodeMap.put(65, "too many sessions on server"); // too many sessions
|
||||||
|
errorCodeMap.put(66, "too many sessions from app"); // too many connections
|
||||||
|
errorCodeMap.put(67, "session to dest is already there");
|
||||||
|
errorCodeMap.put(68, "query list not there); please show again");
|
||||||
|
errorCodeMap.put(69, "server out of memory");
|
||||||
|
errorCodeMap.put(70, "invalid query handle");
|
||||||
|
errorCodeMap.put(71, "tables related to metric exist");
|
||||||
|
errorCodeMap.put(72, "can't drop monitor database or tables");
|
||||||
|
errorCodeMap.put(73, "commit log init failed");
|
||||||
|
errorCodeMap.put(74, "vgroup init failed");
|
||||||
|
errorCodeMap.put(75, "data is already imported");
|
||||||
|
errorCodeMap.put(76, "not supported operation");
|
||||||
|
errorCodeMap.put(77, "invalid query id string");
|
||||||
|
errorCodeMap.put(78, "invalid stream id string");
|
||||||
|
errorCodeMap.put(79, "invalid connection string");
|
||||||
|
errorCodeMap.put(80, "dnode not balanced");
|
||||||
|
errorCodeMap.put(81, "client out of memory");
|
||||||
|
errorCodeMap.put(82, "data value overflow");
|
||||||
|
errorCodeMap.put(83, "query cancelled");
|
||||||
|
errorCodeMap.put(84, "grant points limited");
|
||||||
|
errorCodeMap.put(85, "grant expired");
|
||||||
|
errorCodeMap.put(86, "client no disk space");
|
||||||
|
errorCodeMap.put(87, "DB file corrupted");
|
||||||
|
errorCodeMap.put(88, "version of client and server not match");
|
||||||
|
}
|
||||||
|
|
||||||
|
TSDBError(long code, String message) {
|
||||||
|
this.errCode = code;
|
||||||
|
this.errMessage = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getErrCode() {
|
||||||
|
return this.errCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrMessage() {
|
||||||
|
return this.errMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getErrMessageByCode(long errCode) {
|
||||||
|
return errorCodeMap.get(errCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,300 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.SQLWarning;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TSDBJNIConnector {
|
||||||
|
static volatile Boolean isInitialized = false;
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("taos");
|
||||||
|
System.out.println("java.library.path:" + System.getProperty("java.library.path"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection pointer used in C
|
||||||
|
*/
|
||||||
|
private long taos = TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result set pointer for the current connection
|
||||||
|
*/
|
||||||
|
private long taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* result set status in current connection
|
||||||
|
*/
|
||||||
|
private boolean isResultsetClosed = true;
|
||||||
|
private int affectedRows = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the connection is closed
|
||||||
|
*/
|
||||||
|
public boolean isClosed() {
|
||||||
|
return this.taos == TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the status of last result set in current connection
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isResultsetClosed() {
|
||||||
|
return this.isResultsetClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize static variables in JNI to optimize performance
|
||||||
|
*/
|
||||||
|
public static void init(String configDir, String locale, String charset, String timezone) throws SQLWarning {
|
||||||
|
synchronized (isInitialized) {
|
||||||
|
if (!isInitialized) {
|
||||||
|
initImp(configDir);
|
||||||
|
if (setOptions(0, locale) < 0) {
|
||||||
|
throw new SQLWarning(TSDBConstants.WrapErrMsg("Failed to set locale: " + locale + ". System default will be used."));
|
||||||
|
}
|
||||||
|
if (setOptions(1, charset) < 0) {
|
||||||
|
throw new SQLWarning(TSDBConstants.WrapErrMsg("Failed to set charset: " + charset + ". System default will be used."));
|
||||||
|
}
|
||||||
|
if (setOptions(2, timezone) < 0) {
|
||||||
|
throw new SQLWarning(TSDBConstants.WrapErrMsg("Failed to set timezone: " + timezone + ". System default will be used."));
|
||||||
|
}
|
||||||
|
isInitialized = true;
|
||||||
|
TaosGlobalConfig.setCharset(getTsCharset());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static native void initImp(String configDir);
|
||||||
|
|
||||||
|
public static native int setOptions(int optionIndex, String optionValue);
|
||||||
|
|
||||||
|
public static native String getTsCharset();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get connection pointer
|
||||||
|
*
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException {
|
||||||
|
if (this.taos != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
this.closeConnectionImp(this.taos);
|
||||||
|
this.taos = TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.taos = this.connectImp(host, port, dbName, user, password);
|
||||||
|
if (this.taos == TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg(this.getErrMsg()), "", this.getErrCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private native long connectImp(String host, int port, String dbName, String user, String password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute DML/DDL operation
|
||||||
|
*
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public int executeQuery(String sql) throws SQLException {
|
||||||
|
if (!this.isResultsetClosed) {
|
||||||
|
freeResultSet(taosResultSetPointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
int code;
|
||||||
|
try {
|
||||||
|
code = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg("Unsupported encoding"));
|
||||||
|
}
|
||||||
|
affectedRows = code;
|
||||||
|
if (code < 0) {
|
||||||
|
affectedRows = -1;
|
||||||
|
if (code == TSDBConstants.JNI_TDENGINE_ERROR) {
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg(this.getErrMsg()), "", this.getErrCode());
|
||||||
|
} else {
|
||||||
|
throw new SQLException(TSDBConstants.FixErrMsg(code), "", this.getErrCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try retrieving result set for the executed SQL using the current connection pointer. If the executed
|
||||||
|
// SQL is a DML/DDL which doesn't return a result set, then taosResultSetPointer should be 0L. Otherwise,
|
||||||
|
// taosResultSetPointer should be a non-zero value.
|
||||||
|
taosResultSetPointer = this.getResultSetImp(this.taos);
|
||||||
|
if (taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
isResultsetClosed = false;
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int executeQueryImp(byte[] sqlBytes, long connection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get recent error code by connection
|
||||||
|
*/
|
||||||
|
public int getErrCode() {
|
||||||
|
return Math.abs(this.getErrCodeImp(this.taos));
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int getErrCodeImp(long connection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get recent error message by connection
|
||||||
|
*/
|
||||||
|
public String getErrMsg() {
|
||||||
|
return this.getErrMsgImp(this.taos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private native String getErrMsgImp(long connection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resultset pointer
|
||||||
|
* Each connection should have a single open result set at a time
|
||||||
|
*/
|
||||||
|
public long getResultSet() {
|
||||||
|
return taosResultSetPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private native long getResultSetImp(long connection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free resultset operation from C to release resultset pointer by JNI
|
||||||
|
*/
|
||||||
|
public int freeResultSet(long result) {
|
||||||
|
int res = TSDBConstants.JNI_SUCCESS;
|
||||||
|
if (result != taosResultSetPointer && taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
throw new RuntimeException("Invalid result set pointer");
|
||||||
|
} else if (taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
res = this.freeResultSetImp(this.taos, result);
|
||||||
|
isResultsetClosed = true; // reset resultSetPointer to 0 after freeResultSetImp() return
|
||||||
|
taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
} else {
|
||||||
|
isResultsetClosed = true;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the open result set which is associated to the current connection. If the result set is already
|
||||||
|
* closed, return 0 for success.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int freeResultSet() {
|
||||||
|
int resCode = TSDBConstants.JNI_SUCCESS;
|
||||||
|
if (!isResultsetClosed) {
|
||||||
|
resCode = this.freeResultSetImp(this.taos, this.taosResultSetPointer);
|
||||||
|
taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
isResultsetClosed = true;
|
||||||
|
}
|
||||||
|
return resCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int freeResultSetImp(long connection, long result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get affected rows count
|
||||||
|
*/
|
||||||
|
public int getAffectedRows() {
|
||||||
|
int affectedRows = this.affectedRows;
|
||||||
|
if (affectedRows < 0) {
|
||||||
|
affectedRows = this.getAffectedRowsImp(this.taos);
|
||||||
|
}
|
||||||
|
return affectedRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int getAffectedRowsImp(long connection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get schema metadata
|
||||||
|
*/
|
||||||
|
public int getSchemaMetaData(long resultSet, List<ColumnMetaData> columnMetaData) {
|
||||||
|
return this.getSchemaMetaDataImp(this.taos, resultSet, columnMetaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int getSchemaMetaDataImp(long connection, long resultSet, List<ColumnMetaData> columnMetaData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get one row data
|
||||||
|
*/
|
||||||
|
public int fetchRow(long resultSet, TSDBResultSetRowData rowData) {
|
||||||
|
return this.fetchRowImp(this.taos, resultSet, rowData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int fetchRowImp(long connection, long resultSet, TSDBResultSetRowData rowData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute close operation from C to release connection pointer by JNI
|
||||||
|
*
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public void closeConnection() throws SQLException {
|
||||||
|
int code = this.closeConnectionImp(this.taos);
|
||||||
|
if (code < 0) {
|
||||||
|
throw new SQLException(TSDBConstants.FixErrMsg(code), "", this.getErrCode());
|
||||||
|
} else if (code == 0) {
|
||||||
|
this.taos = TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
} else {
|
||||||
|
throw new SQLException("Undefined error code returned by TDengine when closing a connection");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int closeConnectionImp(long connection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribe to a table in TSDB
|
||||||
|
*/
|
||||||
|
public long subscribe(String host, String user, String password, String database, String table, long time, int period) {
|
||||||
|
return subscribeImp(host, user, password, database, table, time, period);
|
||||||
|
}
|
||||||
|
|
||||||
|
private native long subscribeImp(String host, String user, String password, String database, String table, long time, int period);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consume a subscribed table
|
||||||
|
*/
|
||||||
|
public TSDBResultSetRowData consume(long subscription) {
|
||||||
|
return this.consumeImp(subscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
private native TSDBResultSetRowData consumeImp(long subscription);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsubscribe a table
|
||||||
|
*
|
||||||
|
* @param subscription
|
||||||
|
*/
|
||||||
|
public void unsubscribe(long subscription) {
|
||||||
|
unsubscribeImp(subscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
private native void unsubscribeImp(long subscription);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate if a <I>create table</I> sql statement is correct without actually creating that table
|
||||||
|
*/
|
||||||
|
public boolean validateCreateTableSql(String sql) {
|
||||||
|
long connection = taos;
|
||||||
|
int res = validateCreateTableSqlImp(connection, sql.getBytes());
|
||||||
|
return res != 0 ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes);
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.sql.ParameterMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class TSDBParameterMetaData implements ParameterMetaData {
|
||||||
|
@Override
|
||||||
|
public int getParameterCount() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int isNullable(int param) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSigned(int param) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPrecision(int param) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getScale(int param) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getParameterType(int param) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getParameterTypeName(int param) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getParameterClassName(int param) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getParameterMode(int param) throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,478 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TDengine only supports a subset of the standard SQL, thus this implemetation of the
|
||||||
|
* standard JDBC API contains more or less some adjustments customized for certain
|
||||||
|
* compatibility needs.
|
||||||
|
*/
|
||||||
|
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
|
||||||
|
protected String rawSql;
|
||||||
|
protected String sql;
|
||||||
|
protected ArrayList<Object> parameters = new ArrayList<Object>();
|
||||||
|
|
||||||
|
//start with insert or import and is case-insensitive
|
||||||
|
private static Pattern savePattern = Pattern.compile("(?i)^\\s*(insert|import)");
|
||||||
|
|
||||||
|
// is insert or import
|
||||||
|
private boolean isSaved;
|
||||||
|
|
||||||
|
private SavedPreparedStatement savedPreparedStatement;
|
||||||
|
|
||||||
|
TSDBPreparedStatement(TSDBJNIConnector connecter, String sql) {
|
||||||
|
super(connecter);
|
||||||
|
init(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(String sql) {
|
||||||
|
this.rawSql = sql;
|
||||||
|
preprocessSql();
|
||||||
|
|
||||||
|
this.isSaved = isSavedSql(this.rawSql);
|
||||||
|
if (this.isSaved) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.savedPreparedStatement = new SavedPreparedStatement(this.rawSql, this);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if the precompiled sql is insert or import
|
||||||
|
*
|
||||||
|
* @param sql
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isSavedSql(String sql) {
|
||||||
|
Matcher matcher = savePattern.matcher(sql);
|
||||||
|
return matcher.find();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] executeBatch() throws SQLException {
|
||||||
|
if (isSaved) {
|
||||||
|
return this.savedPreparedStatement.executeBatch();
|
||||||
|
} else {
|
||||||
|
return super.executeBatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Object> getParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParameters(ArrayList<Object> parameters) {
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRawSql() {
|
||||||
|
return rawSql;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some of the SQLs sent by other popular frameworks or tools like Spark, contains syntax that cannot be parsed by
|
||||||
|
* the TDengine client. Thus, some simple parsers/filters are intentionally added in this JDBC implementation in
|
||||||
|
* order to process those supported SQLs.
|
||||||
|
*/
|
||||||
|
private void preprocessSql() {
|
||||||
|
|
||||||
|
/***** For processing some of Spark SQLs*****/
|
||||||
|
// should replace it first
|
||||||
|
this.rawSql = this.rawSql.replaceAll("or (.*) is null", "");
|
||||||
|
this.rawSql = this.rawSql.replaceAll(" where ", " WHERE ");
|
||||||
|
this.rawSql = this.rawSql.replaceAll(" or ", " OR ");
|
||||||
|
this.rawSql = this.rawSql.replaceAll(" and ", " AND ");
|
||||||
|
this.rawSql = this.rawSql.replaceAll(" is null", " IS NULL");
|
||||||
|
this.rawSql = this.rawSql.replaceAll(" is not null", " IS NOT NULL");
|
||||||
|
|
||||||
|
// SELECT * FROM db.tb WHERE 1=0
|
||||||
|
this.rawSql = this.rawSql.replaceAll("WHERE 1=0", "WHERE _c0=1");
|
||||||
|
this.rawSql = this.rawSql.replaceAll("WHERE 1=2", "WHERE _c0=1");
|
||||||
|
|
||||||
|
// SELECT "ts","val" FROM db.tb
|
||||||
|
this.rawSql = this.rawSql.replaceAll("\"", "");
|
||||||
|
|
||||||
|
// SELECT 1 FROM db.tb
|
||||||
|
this.rawSql = this.rawSql.replaceAll("SELECT 1 FROM", "SELECT * FROM");
|
||||||
|
|
||||||
|
// SELECT "ts","val" FROM db.tb WHERE ts < 33 or ts is null
|
||||||
|
this.rawSql = this.rawSql.replaceAll("OR (.*) IS NULL", "");
|
||||||
|
|
||||||
|
// SELECT "ts","val" FROM db.tb WHERE ts is null or ts < 33
|
||||||
|
this.rawSql = this.rawSql.replaceAll("(.*) IS NULL OR", "");
|
||||||
|
|
||||||
|
// SELECT 1 FROM db.tb WHERE (("val" IS NOT NULL) AND ("val" > 50)) AND (ts >= 66)
|
||||||
|
this.rawSql = this.rawSql.replaceAll("\\(\\((.*) IS NOT NULL\\) AND", "(");
|
||||||
|
|
||||||
|
// SELECT 1 FROM db.tb WHERE ("val" IS NOT NULL) AND ("val" > 50) AND (ts >= 66)
|
||||||
|
this.rawSql = this.rawSql.replaceAll("\\((.*) IS NOT NULL\\) AND", "");
|
||||||
|
|
||||||
|
// SELECT "ts","val" FROM db.tb WHERE (("val" IS NOT NULL)) AND (ts < 33 or ts is null)
|
||||||
|
this.rawSql = this.rawSql.replaceAll("\\(\\((.*) IS NOT NULL\\)\\) AND", "");
|
||||||
|
|
||||||
|
/***** For processing inner subqueries *****/
|
||||||
|
Pattern pattern = Pattern.compile("FROM\\s+((\\(.+\\))\\s+SUB_QRY)", Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher matcher = pattern.matcher(rawSql);
|
||||||
|
String tableFullName = "";
|
||||||
|
if (matcher.find() && matcher.groupCount() == 2) {
|
||||||
|
String subQry = matcher.group(2);
|
||||||
|
Pattern pattern1 = Pattern.compile("FROM\\s+(\\w+\\.\\w+)", Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher matcher1 = pattern1.matcher(subQry);
|
||||||
|
if (matcher1.find() && matcher1.groupCount() == 1) {
|
||||||
|
tableFullName = matcher1.group(1);
|
||||||
|
}
|
||||||
|
rawSql = rawSql.replace(matcher.group(1), tableFullName);
|
||||||
|
}
|
||||||
|
/***** for inner queries *****/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate parameters into prepared sql statements
|
||||||
|
*
|
||||||
|
* @return a string of the native sql statement for TSDB
|
||||||
|
*/
|
||||||
|
private String getNativeSql() {
|
||||||
|
this.sql = this.rawSql;
|
||||||
|
for (int i = 0; i < parameters.size(); ++i) {
|
||||||
|
Object para = parameters.get(i);
|
||||||
|
if (para != null) {
|
||||||
|
String paraStr = para.toString();
|
||||||
|
if (para instanceof Timestamp || para instanceof String) {
|
||||||
|
paraStr = "'" + paraStr + "'";
|
||||||
|
}
|
||||||
|
this.sql = this.sql.replaceFirst("[?]", paraStr);
|
||||||
|
} else {
|
||||||
|
this.sql = this.sql.replaceFirst("[?]", "NULL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parameters.clear();
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet executeQuery() throws SQLException {
|
||||||
|
if (isSaved) {
|
||||||
|
this.savedPreparedStatement.executeBatchInternal();
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return super.executeQuery(getNativeSql());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int executeUpdate() throws SQLException {
|
||||||
|
if (isSaved) {
|
||||||
|
return this.savedPreparedStatement.executeBatchInternal();
|
||||||
|
} else {
|
||||||
|
return super.executeUpdate(getNativeSql());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNull(int parameterIndex, int sqlType) throws SQLException {
|
||||||
|
setObject(parameterIndex, new String("NULL"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBoolean(int parameterIndex, boolean x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setByte(int parameterIndex, byte x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShort(int parameterIndex, short x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInt(int parameterIndex, int x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLong(int parameterIndex, long x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFloat(int parameterIndex, float x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDouble(int parameterIndex, double x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setString(int parameterIndex, String x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDate(int parameterIndex, Date x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTime(int parameterIndex, Time x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
|
||||||
|
setObject(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearParameters() throws SQLException {
|
||||||
|
parameters.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setObject(int parameterIndex, Object x) throws SQLException {
|
||||||
|
if (isSaved) {
|
||||||
|
this.savedPreparedStatement.setParam(parameterIndex, x);
|
||||||
|
} else {
|
||||||
|
parameters.add(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute() throws SQLException {
|
||||||
|
if (isSaved) {
|
||||||
|
int result = this.savedPreparedStatement.executeBatchInternal();
|
||||||
|
return result > 0;
|
||||||
|
} else {
|
||||||
|
return super.execute(getNativeSql());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBatch() throws SQLException {
|
||||||
|
if (isSaved) {
|
||||||
|
this.savedPreparedStatement.addBatch();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (this.batchedArgs == null) {
|
||||||
|
batchedArgs = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
super.addBatch(getNativeSql());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRef(int parameterIndex, Ref x) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlob(int parameterIndex, Blob x) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClob(int parameterIndex, Clob x) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setArray(int parameterIndex, Array x) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSetMetaData getMetaData() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setURL(int parameterIndex, URL x) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParameterMetaData getParameterMetaData() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRowId(int parameterIndex, RowId x) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNString(int parameterIndex, String value) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNClob(int parameterIndex, NClob value) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClob(int parameterIndex, Reader reader) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNClob(int parameterIndex, Reader reader) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,213 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TSDBResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
|
List<ColumnMetaData> colMetaDataList = null;
|
||||||
|
|
||||||
|
public TSDBResultSetMetaData(List<ColumnMetaData> metaDataList) {
|
||||||
|
this.colMetaDataList = metaDataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColumnCount() throws SQLException {
|
||||||
|
return colMetaDataList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAutoIncrement(int column) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCaseSensitive(int column) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSearchable(int column) throws SQLException {
|
||||||
|
if (column == 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCurrency(int column) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int isNullable(int column) throws SQLException {
|
||||||
|
if (column == 1) {
|
||||||
|
return columnNoNulls;
|
||||||
|
}
|
||||||
|
return columnNullable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSigned(int column) throws SQLException {
|
||||||
|
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
|
||||||
|
switch (meta.getColType()) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_INT:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColumnDisplaySize(int column) throws SQLException {
|
||||||
|
return colMetaDataList.get(column - 1).getColSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getColumnLabel(int column) throws SQLException {
|
||||||
|
return colMetaDataList.get(column - 1).getColName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getColumnName(int column) throws SQLException {
|
||||||
|
return colMetaDataList.get(column - 1).getColName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSchemaName(int column) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPrecision(int column) throws SQLException {
|
||||||
|
ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1);
|
||||||
|
switch (columnMetaData.getColType()) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
||||||
|
return 5;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
return 9;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||||
|
return columnMetaData.getColSize();
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScale(int column) throws SQLException {
|
||||||
|
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
|
||||||
|
switch (meta.getColType()) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
||||||
|
return 5;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
return 9;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTableName(int column) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCatalogName(int column) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColumnType(int column) throws SQLException {
|
||||||
|
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
|
||||||
|
switch (meta.getColType()) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
|
||||||
|
return java.sql.Types.BIT;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
|
||||||
|
return java.sql.Types.TINYINT;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
return java.sql.Types.SMALLINT;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_INT:
|
||||||
|
return java.sql.Types.INTEGER;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
|
||||||
|
return java.sql.Types.BIGINT;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
||||||
|
return java.sql.Types.FLOAT;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
return java.sql.Types.DOUBLE;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
|
||||||
|
return java.sql.Types.CHAR;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
return java.sql.Types.BIGINT;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||||
|
return java.sql.Types.CHAR;
|
||||||
|
}
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getColumnTypeName(int column) throws SQLException {
|
||||||
|
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
|
||||||
|
return TSDBConstants.DATATYPE_MAP.get(meta.getColType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReadOnly(int column) throws SQLException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWritable(int column) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDefinitelyWritable(int column) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getColumnClassName(int column) throws SQLException {
|
||||||
|
int columnType = getColumnType(column);
|
||||||
|
String columnClassName = "";
|
||||||
|
switch (columnType) {
|
||||||
|
case Types.TIMESTAMP:
|
||||||
|
columnClassName = Timestamp.class.getName();
|
||||||
|
break;
|
||||||
|
case Types.CHAR:
|
||||||
|
columnClassName = String.class.getName();
|
||||||
|
break;
|
||||||
|
case Types.DOUBLE:
|
||||||
|
columnClassName = Double.class.getName();
|
||||||
|
break;
|
||||||
|
case Types.FLOAT:
|
||||||
|
columnClassName = Float.class.getName();
|
||||||
|
break;
|
||||||
|
case Types.BIGINT:
|
||||||
|
columnClassName = Long.class.getName();
|
||||||
|
break;
|
||||||
|
case Types.INTEGER:
|
||||||
|
columnClassName = Integer.class.getName();
|
||||||
|
break;
|
||||||
|
case Types.SMALLINT:
|
||||||
|
columnClassName = Short.class.getName();
|
||||||
|
break;
|
||||||
|
case Types.TINYINT:
|
||||||
|
columnClassName = Byte.class.getName();
|
||||||
|
break;
|
||||||
|
case Types.BIT:
|
||||||
|
columnClassName = Boolean.class.getName();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return columnClassName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,222 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
public class TSDBResultSetRowData {
|
||||||
|
private ArrayList<Object> data = null;
|
||||||
|
private int colSize = 0;
|
||||||
|
|
||||||
|
public TSDBResultSetRowData(int colSize) {
|
||||||
|
this.setColSize(colSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TSDBResultSetRowData() {
|
||||||
|
this.data = new ArrayList<Object>();
|
||||||
|
this.setColSize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
if(this.data != null) {
|
||||||
|
this.data.clear();
|
||||||
|
}
|
||||||
|
if (this.colSize == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.data = new ArrayList<Object>(colSize);
|
||||||
|
this.data.addAll(Collections.nCopies(this.colSize, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean wasNull(int col) {
|
||||||
|
return data.get(col) == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBoolean(int col, boolean value) {
|
||||||
|
data.set(col, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getBoolean(int col, int srcType) throws SQLException {
|
||||||
|
Object obj = data.get(col);
|
||||||
|
|
||||||
|
switch(srcType) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BOOL: return (Boolean) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return ((Float) obj) == 1.0? Boolean.TRUE:Boolean.FALSE;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: return ((Double) obj) == 1.0? Boolean.TRUE:Boolean.FALSE;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return ((Byte) obj) == 1? Boolean.TRUE:Boolean.FALSE;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:return ((Short)obj) == 1? Boolean.TRUE:Boolean.FALSE;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_INT: return ((Integer)obj) == 1? Boolean.TRUE:Boolean.FALSE;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return ((Long) obj) == 1L? Boolean.TRUE:Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boolean.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByte(int col, byte value) {
|
||||||
|
data.set(col, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShort(int col, short value) {
|
||||||
|
data.set(col, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInt(int col, int value) {
|
||||||
|
data.set(col, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt(int col, int srcType) throws SQLException {
|
||||||
|
Object obj = data.get(col);
|
||||||
|
|
||||||
|
switch(srcType) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj)? 1:0;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return ((Float) obj).intValue();
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: return ((Double)obj).intValue();
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:return (Short) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return ((Long) obj).intValue();
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BINARY: return Integer.parseInt((String) obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLong(int col, long value) {
|
||||||
|
data.set(col, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLong(int col, int srcType) throws SQLException {
|
||||||
|
Object obj = data.get(col);
|
||||||
|
|
||||||
|
switch(srcType) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj)? 1:0;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return ((Float) obj).longValue();
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: return ((Double) obj).longValue();
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:return (Short) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return (Long) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BINARY: return Long.parseLong((String) obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFloat(int col, float value) {
|
||||||
|
data.set(col, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getFloat(int col, int srcType) throws SQLException {
|
||||||
|
Object obj = data.get(col);
|
||||||
|
|
||||||
|
switch(srcType) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj)? 1:0;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return (Float) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: return ((Double) obj).floatValue();
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: return (Short) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return (Long) obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDouble(int col, double value) {
|
||||||
|
data.set(col, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDouble(int col, int srcType) throws SQLException {
|
||||||
|
Object obj = data.get(col);
|
||||||
|
|
||||||
|
switch(srcType) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj)? 1:0;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return (Float) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: return (Double) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:return (Short) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj;
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return (Long) obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setString(int col, String value) {
|
||||||
|
data.set(col, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByteArray(int col, byte[] value) {
|
||||||
|
try {
|
||||||
|
data.set(col, new String(value, TaosGlobalConfig.getCharset()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The original type may not be a string type, but will be converted to by calling this method
|
||||||
|
* @param col column index
|
||||||
|
* @return
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public String getString(int col, int srcType) throws SQLException {
|
||||||
|
if (srcType == TSDBConstants.TSDB_DATA_TYPE_BINARY || srcType == TSDBConstants.TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
return (String) data.get(col);
|
||||||
|
} else {
|
||||||
|
return String.valueOf(data.get(col));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(int col, long ts) {
|
||||||
|
data.set(col, ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timestamp getTimestamp(int col) {
|
||||||
|
return new Timestamp((Long) data.get(col));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(int col) {
|
||||||
|
return data.get(col);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColSize() {
|
||||||
|
return colSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColSize(int colSize) {
|
||||||
|
this.colSize = colSize;
|
||||||
|
this.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Object> getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(ArrayList<Object> data) {
|
||||||
|
this.data = (ArrayList<Object>) data.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,294 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TSDBStatement implements Statement {
|
||||||
|
private TSDBJNIConnector connecter = null;
|
||||||
|
|
||||||
|
/** To store batched commands */
|
||||||
|
protected List<String> batchedArgs;
|
||||||
|
|
||||||
|
/** Timeout for a query */
|
||||||
|
protected int queryTimeout = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Status of current statement
|
||||||
|
*/
|
||||||
|
private boolean isClosed = true;
|
||||||
|
|
||||||
|
TSDBStatement(TSDBJNIConnector connecter) {
|
||||||
|
this.connecter = connecter;
|
||||||
|
this.isClosed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet executeQuery(String sql) throws SQLException {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
|
this.connecter.executeQuery(sql);
|
||||||
|
|
||||||
|
long resultSetPointer = this.connecter.getResultSet();
|
||||||
|
|
||||||
|
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||||
|
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||||
|
} else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return new TSDBResultSet(this.connecter, resultSetPointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int executeUpdate(String sql) throws SQLException {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
|
int res = this.connecter.executeQuery(sql);
|
||||||
|
long resultSetPointer = this.connecter.getResultSet();
|
||||||
|
|
||||||
|
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||||
|
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||||
|
} else if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
this.connecter.freeResultSet();
|
||||||
|
throw new SQLException("The executed SQL is not a DML or a DDL");
|
||||||
|
} else {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrorMsg() {
|
||||||
|
return this.connecter.getErrMsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws SQLException {
|
||||||
|
if (!isClosed) {
|
||||||
|
if (!this.connecter.isResultsetClosed()) {
|
||||||
|
this.connecter.freeResultSet();
|
||||||
|
}
|
||||||
|
isClosed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxFieldSize() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxFieldSize(int max) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxRows() throws SQLException {
|
||||||
|
// always set maxRows to zero, meaning unlimitted rows in a resultSet
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxRows(int max) throws SQLException {
|
||||||
|
// always set maxRows to zero, meaning unlimitted rows in a resultSet
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEscapeProcessing(boolean enable) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getQueryTimeout() throws SQLException {
|
||||||
|
return queryTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQueryTimeout(int seconds) throws SQLException {
|
||||||
|
this.queryTimeout = seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SQLWarning getWarnings() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearWarnings() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCursorName(String name) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean execute(String sql) throws SQLException {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
|
boolean res = true;
|
||||||
|
this.connecter.executeQuery(sql);
|
||||||
|
long resultSetPointer = this.connecter.getResultSet();
|
||||||
|
|
||||||
|
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||||
|
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||||
|
} else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
// no result set is retrieved
|
||||||
|
res = false;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getResultSet() throws SQLException {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
|
long resultSetPointer = connecter.getResultSet();
|
||||||
|
TSDBResultSet resSet = null;
|
||||||
|
if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
resSet = new TSDBResultSet(connecter, resultSetPointer);
|
||||||
|
}
|
||||||
|
return resSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUpdateCount() throws SQLException {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
|
return this.connecter.getAffectedRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getMoreResults() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFetchDirection(int direction) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFetchDirection() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* used by spark
|
||||||
|
*/
|
||||||
|
public void setFetchSize(int rows) throws SQLException {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* used by spark
|
||||||
|
*/
|
||||||
|
public int getFetchSize() throws SQLException {
|
||||||
|
return 4096;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getResultSetConcurrency() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getResultSetType() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBatch(String sql) throws SQLException {
|
||||||
|
if (batchedArgs == null) {
|
||||||
|
batchedArgs = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
batchedArgs.add(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearBatch() throws SQLException {
|
||||||
|
batchedArgs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] executeBatch() throws SQLException {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
|
if (batchedArgs == null) {
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg("Batch is empty!"));
|
||||||
|
} else {
|
||||||
|
int[] res = new int[batchedArgs.size()];
|
||||||
|
for (int i = 0; i < batchedArgs.size(); i++) {
|
||||||
|
res[i] = executeUpdate(batchedArgs.get(i));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection getConnection() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getMoreResults(int current) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getGeneratedKeys() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean execute(String sql, int[] columnIndexes) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean execute(String sql, String[] columnNames) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getResultSetHoldability() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isClosed() throws SQLException {
|
||||||
|
return isClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoolable(boolean poolable) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPoolable() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeOnCompletion() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCloseOnCompletion() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
public class TaosGlobalConfig {
|
||||||
|
static String charset = "";
|
||||||
|
|
||||||
|
public static String getCharset() {
|
||||||
|
if (charset == null || charset.isEmpty()) {
|
||||||
|
charset = System.getProperty("file.encoding");
|
||||||
|
}
|
||||||
|
return charset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setCharset(String tsCharset) {
|
||||||
|
TaosGlobalConfig.charset = tsCharset;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.taosdata.jdbc.bean;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tdengine batch insert or import param object
|
||||||
|
*/
|
||||||
|
public class TSDBPreparedParam {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tableName, if sTable Name is not null, and this is sub table name.
|
||||||
|
*/
|
||||||
|
private String tableName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sub middle param list
|
||||||
|
*/
|
||||||
|
private List<Object> middleParamList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* value list
|
||||||
|
*/
|
||||||
|
private List<Object> valueList;
|
||||||
|
|
||||||
|
public TSDBPreparedParam(String tableName) {
|
||||||
|
this.tableName = tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTableName() {
|
||||||
|
return tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableName(String tableName) {
|
||||||
|
this.tableName = tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Object> getMiddleParamList() {
|
||||||
|
return middleParamList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMiddleParamList(List<Object> middleParamList) {
|
||||||
|
this.middleParamList = middleParamList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMiddleParam(int parameterIndex, Object x) {
|
||||||
|
this.middleParamList.set(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Object> getValueList() {
|
||||||
|
return valueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValueList(List<Object> valueList) {
|
||||||
|
this.valueList = valueList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setValueParam(int parameterIndex, Object x) {
|
||||||
|
this.valueList.set(parameterIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc.utils;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.TSDBConnection;
|
||||||
|
import com.taosdata.jdbc.TSDBJNIConnector;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class SqlSyntaxValidator {
|
||||||
|
|
||||||
|
private TSDBConnection tsdbConnection;
|
||||||
|
public SqlSyntaxValidator(Connection connection) {
|
||||||
|
this.tsdbConnection = (TSDBConnection) connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validateSqlSyntax(String sql) throws SQLException {
|
||||||
|
|
||||||
|
boolean res = false;
|
||||||
|
if (tsdbConnection == null || tsdbConnection.isClosed()) {
|
||||||
|
throw new SQLException("invalid connection");
|
||||||
|
} else {
|
||||||
|
TSDBJNIConnector jniConnector = tsdbConnection.getConnection();
|
||||||
|
if (jniConnector == null) {
|
||||||
|
throw new SQLException("jniConnector is null");
|
||||||
|
} else {
|
||||||
|
res = jniConnector.validateCreateTableSql(sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
|
@ -46,8 +46,9 @@ typedef struct {
|
||||||
} SRpcIpSet;
|
} SRpcIpSet;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t sourceIp;
|
uint32_t clientIp;
|
||||||
uint16_t sourcePort;
|
uint16_t clientPort;
|
||||||
|
uint32_t serverIp;
|
||||||
char *user;
|
char *user;
|
||||||
} SRpcConnInfo;
|
} SRpcConnInfo;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
PROJECT(TDengine)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc)
|
||||||
|
INCLUDE_DIRECTORIES(inc)
|
||||||
|
|
||||||
|
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||||
|
AUX_SOURCE_DIRECTORY(./src SRC)
|
||||||
|
ELSEIF (TD_DARWIN_64)
|
||||||
|
LIST(APPEND SRC ./src/thaship.c)
|
||||||
|
LIST(APPEND SRC ./src/trpc.c)
|
||||||
|
LIST(APPEND SRC ./src/tstring.c)
|
||||||
|
LIST(APPEND SRC ./src/tudp.c)
|
||||||
|
ELSEIF (TD_WINDOWS_64)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/pthread)
|
||||||
|
LIST(APPEND SRC ./src/thaship.c)
|
||||||
|
LIST(APPEND SRC ./src/trpc.c)
|
||||||
|
LIST(APPEND SRC ./src/tstring.c)
|
||||||
|
LIST(APPEND SRC ./src/tudp.c)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
ADD_LIBRARY(trpc ${SRC})
|
||||||
|
TARGET_LINK_LIBRARIES(trpc tutil)
|
|
@ -32,6 +32,7 @@ typedef struct {
|
||||||
uint32_t uid; // for unique ID inside a client
|
uint32_t uid; // for unique ID inside a client
|
||||||
uint32_t sourceId; // source ID, an index for connection list
|
uint32_t sourceId; // source ID, an index for connection list
|
||||||
uint32_t destId; // destination ID, an index for connection list
|
uint32_t destId; // destination ID, an index for connection list
|
||||||
|
uint32_t destIp; // destination IP address, for NAT scenario
|
||||||
char user[TSDB_UNI_LEN];
|
char user[TSDB_UNI_LEN];
|
||||||
uint16_t port; // for UDP only, port may be changed
|
uint16_t port; // for UDP only, port may be changed
|
||||||
char empty[1]; // reserved
|
char empty[1]; // reserved
|
||||||
|
|
|
@ -94,6 +94,7 @@ typedef struct _RpcConn {
|
||||||
uint16_t localPort; // for UDP only
|
uint16_t localPort; // for UDP only
|
||||||
uint32_t peerUid; // peer UID
|
uint32_t peerUid; // peer UID
|
||||||
uint32_t peerIp; // peer IP
|
uint32_t peerIp; // peer IP
|
||||||
|
uint32_t destIp; // server destination IP to handle NAT
|
||||||
uint16_t peerPort; // peer port
|
uint16_t peerPort; // peer port
|
||||||
char peerIpstr[TSDB_IPv4ADDR_LEN]; // peer IP string
|
char peerIpstr[TSDB_IPv4ADDR_LEN]; // peer IP string
|
||||||
uint16_t tranId; // outgoing transcation ID, for build message
|
uint16_t tranId; // outgoing transcation ID, for build message
|
||||||
|
@ -389,8 +390,9 @@ void rpcGetConnInfo(void *thandle, SRpcConnInfo *pInfo) {
|
||||||
SRpcConn *pConn = (SRpcConn *)thandle;
|
SRpcConn *pConn = (SRpcConn *)thandle;
|
||||||
SRpcInfo *pRpc = pConn->pRpc;
|
SRpcInfo *pRpc = pConn->pRpc;
|
||||||
|
|
||||||
pInfo->sourceIp = pConn->peerIp;
|
pInfo->clientIp = pConn->peerIp;
|
||||||
pInfo->sourcePort = pConn->peerPort;
|
pInfo->clientPort = pConn->peerPort;
|
||||||
|
pInfo->serverIp = pConn->destIp;
|
||||||
strcpy(pInfo->user, pConn->user);
|
strcpy(pInfo->user, pConn->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,6 +548,7 @@ SRpcConn *rpcSetConnToServer(SRpcInfo *pRpc, SRpcIpSet ipSet) {
|
||||||
char ipstr[20] = {0};
|
char ipstr[20] = {0};
|
||||||
tinet_ntoa(ipstr, ipSet.ip[ipSet.index]);
|
tinet_ntoa(ipstr, ipSet.ip[ipSet.index]);
|
||||||
pConn = rpcOpenConn(pRpc, ipstr, ipSet.port);
|
pConn = rpcOpenConn(pRpc, ipstr, ipSet.port);
|
||||||
|
pConn->destIp = ipSet.ip[ipSet.index];
|
||||||
}
|
}
|
||||||
|
|
||||||
return pConn;
|
return pConn;
|
||||||
|
@ -772,11 +775,13 @@ static void *rpcProcessMsgFromPeer(void *msg, int msgLen, uint32_t ip, uint16_t
|
||||||
|
|
||||||
static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead) {
|
static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead) {
|
||||||
SRpcInfo *pRpc = pConn->pRpc;
|
SRpcInfo *pRpc = pConn->pRpc;
|
||||||
|
|
||||||
pHead = rpcDecompressRpcMsg(pHead);
|
pHead = rpcDecompressRpcMsg(pHead);
|
||||||
int contLen = rpcContLenFromMsg(pHead->msgLen);
|
int contLen = rpcContLenFromMsg(pHead->msgLen);
|
||||||
uint8_t *pCont = pHead->content;
|
uint8_t *pCont = pHead->content;
|
||||||
|
|
||||||
if ( rpcIsReq(pHead->msgType) ) {
|
if ( rpcIsReq(pHead->msgType) ) {
|
||||||
|
pConn->destIp = pHead->destIp;
|
||||||
taosTmrReset(rpcProcessProgressTimer, tsRpcTimer/2, pConn, pRpc->tmrCtrl, &pConn->pTimer);
|
taosTmrReset(rpcProcessProgressTimer, tsRpcTimer/2, pConn, pRpc->tmrCtrl, &pConn->pTimer);
|
||||||
(*(pRpc->cfp))(pHead->msgType, pCont, contLen, pConn, 0);
|
(*(pRpc->cfp))(pHead->msgType, pCont, contLen, pConn, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -886,6 +891,7 @@ static void rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) {
|
||||||
pHead->tranId = pConn->tranId;
|
pHead->tranId = pConn->tranId;
|
||||||
pHead->sourceId = pConn->ownId;
|
pHead->sourceId = pConn->ownId;
|
||||||
pHead->destId = pConn->peerId;
|
pHead->destId = pConn->peerId;
|
||||||
|
pHead->destIp = pConn->destIp;
|
||||||
pHead->port = 0;
|
pHead->port = 0;
|
||||||
pHead->uid = (uint32_t)((int64_t)pConn + (int64_t)getpid());
|
pHead->uid = (uint32_t)((int64_t)pConn + (int64_t)getpid());
|
||||||
memcpy(pHead->user, pConn->user, tListLen(pHead->user));
|
memcpy(pHead->user, pConn->user, tListLen(pHead->user));
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
import com.datastax.oss.driver.api.core.CqlSession;
|
||||||
|
import com.datastax.oss.driver.api.core.cql.*;
|
||||||
|
import com.datastax.oss.driver.api.core.session.*;
|
||||||
|
import com.datastax.oss.driver.api.core.config.*;
|
||||||
|
import com.datastax.oss.driver.api.core.cql.ResultSet;
|
||||||
|
import com.datastax.oss.driver.api.core.cql.Row;
|
||||||
|
//import com.datastax.driver.core.Cluster;
|
||||||
|
//import com.datastax.driver.core.Cluster;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.math.*;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
|
||||||
|
public class CassandraTest{
|
||||||
|
|
||||||
|
public static void main(String args[]) {
|
||||||
|
|
||||||
|
|
||||||
|
// begin to parse argument
|
||||||
|
String datadir = "/home/ubuntu/testdata";
|
||||||
|
String sqlfile = "/home/ubuntu/fang/cassandra/q1.txt";
|
||||||
|
String cfgfile = "/home/ubuntu/fang/cassandra/application.conf";
|
||||||
|
boolean q4flag = false;
|
||||||
|
int numOfRows = 1000000;
|
||||||
|
int numOfFiles =0;
|
||||||
|
int numOfClients =0;
|
||||||
|
int rowsPerRequest =0;
|
||||||
|
for (int i = 0; i < args.length; ++i) {
|
||||||
|
if (args[i].equalsIgnoreCase("-dataDir")) {
|
||||||
|
if (i < args.length - 1) {
|
||||||
|
datadir = args[++i];
|
||||||
|
}
|
||||||
|
} else if (args[i].equalsIgnoreCase("-numofFiles")) {
|
||||||
|
if (i < args.length - 1) {
|
||||||
|
numOfFiles = Integer.parseInt(args[++i]);
|
||||||
|
}
|
||||||
|
} else if (args[i].equalsIgnoreCase("-rowsPerRequest")) {
|
||||||
|
if (i < args.length - 1) {
|
||||||
|
rowsPerRequest = Integer.parseInt(args[++i]);
|
||||||
|
}
|
||||||
|
} else if (args[i].equalsIgnoreCase("-writeClients")) {
|
||||||
|
if (i < args.length - 1) {
|
||||||
|
numOfClients = Integer.parseInt(args[++i]);
|
||||||
|
}
|
||||||
|
} else if (args[i].equalsIgnoreCase("-sql")) {
|
||||||
|
sqlfile = args[++i];
|
||||||
|
} else if (args[i].equalsIgnoreCase("-timetest")) {
|
||||||
|
q4flag = true;
|
||||||
|
} else if (args[i].equalsIgnoreCase("-conf")) {
|
||||||
|
cfgfile = args[++i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// file below to make sure no timeout error
|
||||||
|
File confile = new File(cfgfile);
|
||||||
|
|
||||||
|
System.out.println("parameters\n");
|
||||||
|
|
||||||
|
if (numOfFiles >0) {
|
||||||
|
// write data
|
||||||
|
System.out.printf("----dataDir:%s\n", datadir);
|
||||||
|
System.out.printf("----numOfFiles:%d\n", numOfFiles);
|
||||||
|
System.out.printf("----numOfClients:%d\n", numOfClients);
|
||||||
|
System.out.printf("----rowsPerRequest:%d\n", rowsPerRequest);
|
||||||
|
|
||||||
|
// connect to cassandra server
|
||||||
|
System.out.printf("----connecting to cassandra server\n");
|
||||||
|
try {
|
||||||
|
CqlSession session = CqlSession.builder()
|
||||||
|
.withConfigLoader(DriverConfigLoader.fromFile(confile))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
session.execute("drop keyspace if exists cassandra");
|
||||||
|
session.execute("CREATE KEYSPACE if not exists cassandra WITH replication = {'class':'SimpleStrategy', 'replication_factor':1}");
|
||||||
|
if (q4flag) {
|
||||||
|
session.execute("create table if not exists cassandra.test (devid int, devname text, devgroup int, ts bigint, minute bigint, temperature int, humidity float ,primary key (minute,ts,devgroup,devid,devname))");
|
||||||
|
} else {
|
||||||
|
session.execute("create table if not exists cassandra.test (devid int, devname text, devgroup int, ts bigint, temperature int, humidity float ,primary key (devgroup,devid,devname,ts))");
|
||||||
|
}
|
||||||
|
session.close();
|
||||||
|
System.out.printf("----created keyspace cassandra and table test\n");
|
||||||
|
|
||||||
|
// begin to insert data
|
||||||
|
System.out.printf("----begin to insert data\n");
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
int a = numOfFiles/numOfClients;
|
||||||
|
int b = numOfFiles%numOfClients;
|
||||||
|
int last = 0;
|
||||||
|
|
||||||
|
WriteThread[] writethreads = new WriteThread[numOfClients];
|
||||||
|
int[] wargs = new int[2]; // data file start, end
|
||||||
|
wargs[0] = numOfRows; //rows to be read from each file
|
||||||
|
wargs[1] = rowsPerRequest;
|
||||||
|
int fstart =0;
|
||||||
|
int fend =0;
|
||||||
|
for (int i = 0; i<numOfClients; ++i) {
|
||||||
|
if (i<b) {
|
||||||
|
fstart = last;
|
||||||
|
fend = last+a;
|
||||||
|
last = last+a+1;
|
||||||
|
writethreads[i] = new WriteThread(fstart,fend,wargs,datadir,q4flag);
|
||||||
|
System.out.printf("----Thread %d begin to write\n",i);
|
||||||
|
writethreads[i].start();
|
||||||
|
} else {
|
||||||
|
fstart = last;
|
||||||
|
fend = last+a-1;
|
||||||
|
last = last+a;
|
||||||
|
writethreads[i] = new WriteThread(fstart,fend,wargs,datadir,q4flag);
|
||||||
|
System.out.printf("----Thread %d begin to write\n",i);
|
||||||
|
writethreads[i].start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i =0; i<numOfClients; ++i) {
|
||||||
|
try {
|
||||||
|
writethreads[i].join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long stopTime = System.currentTimeMillis();
|
||||||
|
float elapseTime = stopTime - startTime;
|
||||||
|
elapseTime = elapseTime/1000;
|
||||||
|
float speeds = numOfRows*numOfFiles/elapseTime;
|
||||||
|
System.out.printf("---- insertation speed: %f Rows/Second\n",speeds);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
System.exit(1);
|
||||||
|
} finally {
|
||||||
|
System.out.printf("---- insertion end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// above:write part; below: read part;
|
||||||
|
} else {
|
||||||
|
// query data begin
|
||||||
|
System.out.printf("----sql command file:%s\n", sqlfile);
|
||||||
|
// connect to cassandra server
|
||||||
|
try {
|
||||||
|
CqlSession session = CqlSession.builder()
|
||||||
|
.withConfigLoader(DriverConfigLoader.fromFile(confile))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//session.execute("use cassandra;");
|
||||||
|
BufferedReader br = null;
|
||||||
|
String line = "";
|
||||||
|
try {
|
||||||
|
br = new BufferedReader(new FileReader(sqlfile));
|
||||||
|
while ((line = br.readLine()) != null && line.length()>10) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
// begin to query one line command //
|
||||||
|
// end querying one line command
|
||||||
|
try {
|
||||||
|
|
||||||
|
ResultSet results = session.execute(line);
|
||||||
|
long icounter = 0;
|
||||||
|
for (Row row : results) {
|
||||||
|
icounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
long stopTime = System.currentTimeMillis();
|
||||||
|
float elapseTime = stopTime - startTime;
|
||||||
|
elapseTime = elapseTime/1000;
|
||||||
|
System.out.printf("----spend %f seconds to query: %s\n", elapseTime, line);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
System.out.printf("---- query failed!\n");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (br != null) {
|
||||||
|
try {
|
||||||
|
br.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
System.out.println("query end:----\n");
|
||||||
|
}
|
||||||
|
} // end write or query
|
||||||
|
System.exit(0);
|
||||||
|
}// end main
|
||||||
|
}// end class
|
|
@ -0,0 +1,99 @@
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.*;
|
||||||
|
|
||||||
|
import com.datastax.oss.driver.api.core.CqlSession;
|
||||||
|
import com.datastax.oss.driver.api.core.cql.*;
|
||||||
|
import com.datastax.oss.driver.api.core.session.*;
|
||||||
|
import com.datastax.oss.driver.api.core.config.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class WriteThread extends Thread {
|
||||||
|
|
||||||
|
private int[] wargs; // fstart, fend, rows to be read, rows perrequest
|
||||||
|
private String fdir;
|
||||||
|
private int fstart;
|
||||||
|
private int fend;
|
||||||
|
private boolean q4flag;
|
||||||
|
|
||||||
|
public WriteThread (int fstart, int fend,int[] wargs, String fdir, boolean q4flag) {
|
||||||
|
this.fstart = fstart;
|
||||||
|
this.fend = fend;
|
||||||
|
this.fdir = fdir;
|
||||||
|
this.wargs = wargs;
|
||||||
|
this.q4flag = q4flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
// begin to insert in this thread
|
||||||
|
public void run() {
|
||||||
|
/*
|
||||||
|
// this configuration file makes sure no timeout error
|
||||||
|
File confile = new File("/home/ubuntu/fang/cassandra/application.conf");
|
||||||
|
*/
|
||||||
|
// connect to server
|
||||||
|
try {
|
||||||
|
CqlSession session = CqlSession.builder()
|
||||||
|
//.withConfigLoader(DriverConfigLoader.fromFile(confile))
|
||||||
|
.build();
|
||||||
|
//session.execute("use cassandra");
|
||||||
|
int tominute = 6000;
|
||||||
|
for (int i=fstart; i<=fend; i++) {
|
||||||
|
String csvfile;
|
||||||
|
csvfile = fdir + "/testdata"+ Integer.toString(i)+".csv";
|
||||||
|
BufferedReader br = null;
|
||||||
|
String line = "";
|
||||||
|
String cvsSplitBy = " ";
|
||||||
|
try {
|
||||||
|
br = new BufferedReader(new FileReader(csvfile));
|
||||||
|
System.out.println("---- begin to read file " +csvfile+"\n");
|
||||||
|
for (int itotalrow =0; itotalrow<wargs[0]; itotalrow=itotalrow+wargs[1]) {
|
||||||
|
String cqlstr = "BEGIN BATCH ";
|
||||||
|
for (int irow =0; irow<wargs[1]; ++irow) {
|
||||||
|
line = br.readLine();
|
||||||
|
if (line !=null) {
|
||||||
|
String[] meter = line.split(cvsSplitBy);
|
||||||
|
BigInteger tminute = new BigInteger(meter[3]);
|
||||||
|
tminute = tminute.divide(BigInteger.valueOf(tominute));
|
||||||
|
if (q4flag) {
|
||||||
|
cqlstr = cqlstr + "insert into cassandra.test (devid,devname,devgroup,ts, minute,temperature,humidity) values ";
|
||||||
|
cqlstr = cqlstr +"("+meter[0] +"," +"'" +meter[1] +"'" +"," +meter[2] +"," + meter[3] +",";
|
||||||
|
cqlstr = cqlstr +tminute.toString() +"," +meter[4] +"," +meter[5] +");";
|
||||||
|
} else {
|
||||||
|
cqlstr = cqlstr + "insert into cassandra.test (devid,devname,devgroup,ts,temperature,humidity) values ";
|
||||||
|
cqlstr = cqlstr +"("+meter[0] +"," +"'" +meter[1] +"'" +"," +meter[2] +"," + meter[3] +",";
|
||||||
|
cqlstr = cqlstr +meter[4] +"," +meter[5] +");";
|
||||||
|
}
|
||||||
|
} // if this line is not null
|
||||||
|
}//end row iteration in one batch
|
||||||
|
cqlstr = cqlstr+" APPLY BATCH;";
|
||||||
|
try {
|
||||||
|
//System.out.println(cqlstr+"----\n");
|
||||||
|
session.execute(cqlstr);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}// end one file reading
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (br != null) {
|
||||||
|
try {
|
||||||
|
br.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//end file iteration
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}//end run
|
||||||
|
}//end class
|
|
@ -0,0 +1,468 @@
|
||||||
|
import com.stumbleupon.async.Callback;
|
||||||
|
import com.stumbleupon.async.Deferred;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import net.opentsdb.core.TSDB;
|
||||||
|
import net.opentsdb.uid.NoSuchUniqueName;
|
||||||
|
import net.opentsdb.uid.UniqueId.UniqueIdType;
|
||||||
|
import net.opentsdb.utils.Config;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.ResponseHandler;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.concurrent.FutureCallback;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.math.*;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
|
||||||
|
public class OpentsdbTest{
|
||||||
|
|
||||||
|
//static { System.setProperty("logback.configurationFile", "/home/ubuntu/fang/opentsdb/opentsdbtest/logback.xml");}
|
||||||
|
static { System.setProperty("logback.configurationFile", "/etc/opentsdb/logback.xml");}
|
||||||
|
|
||||||
|
public static void main(String args[]) {
|
||||||
|
// begin to parse argument
|
||||||
|
String datadir = "/home/ubuntu/testdata";
|
||||||
|
String sqlchoice = "q1";
|
||||||
|
int numOfRows = 1000000;
|
||||||
|
int numOfFiles = 0;
|
||||||
|
int numOfClients = 1;
|
||||||
|
int rowsPerRequest = 1;
|
||||||
|
for (int i = 0; i < args.length; ++i) {
|
||||||
|
if (args[i].equalsIgnoreCase("-dataDir")) {
|
||||||
|
if (i < args.length - 1) {
|
||||||
|
datadir = args[++i];
|
||||||
|
}
|
||||||
|
} else if (args[i].equalsIgnoreCase("-numofFiles")) {
|
||||||
|
if (i < args.length - 1) {
|
||||||
|
numOfFiles = Integer.parseInt(args[++i]);
|
||||||
|
}
|
||||||
|
} else if (args[i].equalsIgnoreCase("-rowsPerRequest")) {
|
||||||
|
if (i < args.length - 1) {
|
||||||
|
rowsPerRequest = Integer.parseInt(args[++i]);
|
||||||
|
}
|
||||||
|
} else if (args[i].equalsIgnoreCase("-writeClients")) {
|
||||||
|
if (i < args.length - 1) {
|
||||||
|
numOfClients = Integer.parseInt(args[++i]);
|
||||||
|
}
|
||||||
|
} else if (args[i].equalsIgnoreCase("-sql")) {
|
||||||
|
sqlchoice = args[++i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("parameters:\n");
|
||||||
|
|
||||||
|
|
||||||
|
if (numOfFiles >0) {
|
||||||
|
// write data
|
||||||
|
System.out.printf("----dataDir:%s\n", datadir);
|
||||||
|
System.out.printf("----numOfFiles:%d\n", numOfFiles);
|
||||||
|
System.out.printf("----numOfClients:%d\n", numOfClients);
|
||||||
|
System.out.printf("----rowsPerRequest:%d\n", rowsPerRequest);
|
||||||
|
try {
|
||||||
|
// begin to insert data
|
||||||
|
System.out.printf("----begin to insert data\n");
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
int a = numOfFiles/numOfClients;
|
||||||
|
int b = numOfFiles%numOfClients;
|
||||||
|
int last = 0;
|
||||||
|
|
||||||
|
WriteThread[] writethreads = new WriteThread[numOfClients];
|
||||||
|
int[] wargs = new int[2]; // data file start, end
|
||||||
|
wargs[0] = numOfRows; //rows to be read from each file
|
||||||
|
wargs[1] = rowsPerRequest;
|
||||||
|
int fstart =0;
|
||||||
|
int fend =0;
|
||||||
|
for (int i = 0; i<numOfClients; ++i) {
|
||||||
|
if (i<b) {
|
||||||
|
fstart = last;
|
||||||
|
fend = last+a;
|
||||||
|
last = last+a+1;
|
||||||
|
writethreads[i] = new WriteThread(fstart,fend,wargs,datadir);
|
||||||
|
System.out.printf("----Thread %d begin to write\n",i);
|
||||||
|
writethreads[i].start();
|
||||||
|
} else {
|
||||||
|
fstart = last;
|
||||||
|
fend = last+a-1;
|
||||||
|
last = last+a;
|
||||||
|
writethreads[i] = new WriteThread(fstart,fend,wargs,datadir);
|
||||||
|
System.out.printf("----Thread %d begin to write\n",i);
|
||||||
|
writethreads[i].start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i =0; i<numOfClients; ++i) {
|
||||||
|
try {
|
||||||
|
writethreads[i].join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long stopTime = System.currentTimeMillis();
|
||||||
|
float elapseTime = stopTime - startTime;
|
||||||
|
elapseTime = elapseTime/1000;
|
||||||
|
float speeds = numOfRows*numOfFiles/elapseTime;
|
||||||
|
System.out.printf("---- insertation speed: %f Rows/Second\n",speeds);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
System.exit(1);
|
||||||
|
} finally {
|
||||||
|
System.out.printf("---- insertion end\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// above:write part; below: read part;
|
||||||
|
} else {
|
||||||
|
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
|
||||||
|
String filter_reg;
|
||||||
|
String get_url;
|
||||||
|
long startTime;
|
||||||
|
long stopTime;
|
||||||
|
float elapseTime;
|
||||||
|
CloseableHttpResponse responseBody;
|
||||||
|
StringEntity stringEntity;
|
||||||
|
HttpPost httpPost;
|
||||||
|
String qjson;
|
||||||
|
for (int ig = 10; ig <110; ig = ig+10) {
|
||||||
|
if (ig == 10) {
|
||||||
|
filter_reg = "\\b[0-9]\\b";
|
||||||
|
} else {
|
||||||
|
filter_reg = "\\b" + "([0-9]|"
|
||||||
|
+ "[" + "1" + "-"
|
||||||
|
+ Integer.toString(ig/10-1) + "][0-9])" +"\\b";
|
||||||
|
}
|
||||||
|
switch (sqlchoice) {
|
||||||
|
case "q1":
|
||||||
|
get_url = "http://192.168.1.114:4242/api/query?";
|
||||||
|
/*
|
||||||
|
get_url = get_url + "start=1563249700&m=none:temperature{devgroup=";
|
||||||
|
get_url = get_url + String.valueOf(ig-10) +"}";
|
||||||
|
*/
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
httpPost = new HttpPost(get_url);
|
||||||
|
qjson = " {\n" +
|
||||||
|
" \"start\": 1563249700,\n" +
|
||||||
|
" \"queries\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"aggregator\": \"none\",\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"tags\": {\n" +
|
||||||
|
" \"devgroup\": " + "\"" + Integer.toString(ig-10) + "\"" + "\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }";
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setHeader("Content-type", "application/json");
|
||||||
|
stringEntity = new StringEntity(qjson);
|
||||||
|
httpPost.setEntity(stringEntity);
|
||||||
|
responseBody = httpclient.execute(httpPost);
|
||||||
|
/*
|
||||||
|
System.out.println(responseBody.getStatusLine());
|
||||||
|
System.out.println(qjson);
|
||||||
|
*/
|
||||||
|
responseBody.close();
|
||||||
|
stopTime = System.currentTimeMillis();
|
||||||
|
elapseTime = stopTime - startTime;
|
||||||
|
elapseTime = elapseTime/1000;
|
||||||
|
System.out.printf("Spend %f seconds to get data when devgroup = %d\n",elapseTime, ig-10);
|
||||||
|
break;
|
||||||
|
case "q2":
|
||||||
|
//count
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
get_url = "http://192.168.1.114:4242/api/query?";
|
||||||
|
httpPost = new HttpPost(get_url);
|
||||||
|
qjson = " {\n" +
|
||||||
|
" \"start\": 1563249700,\n" +
|
||||||
|
" \"queries\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"aggregator\": \"count\",\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"filters\": [\n"+
|
||||||
|
" {\n" +
|
||||||
|
" \"type\": \"regexp\",\n" +
|
||||||
|
" \"tagk\": \"devgroup\",\n" +
|
||||||
|
" \"filter\": " +"\"" + filter_reg +"\"" + ",\n" +
|
||||||
|
" \"groupby\": false\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }";
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setHeader("Content-type", "application/json");
|
||||||
|
stringEntity = new StringEntity(qjson);
|
||||||
|
httpPost.setEntity(stringEntity);
|
||||||
|
responseBody = httpclient.execute(httpPost);
|
||||||
|
stopTime = System.currentTimeMillis();
|
||||||
|
elapseTime = stopTime - startTime;
|
||||||
|
elapseTime = elapseTime/1000;
|
||||||
|
System.out.printf("Spend %f seconds to count data when devgroup < %d\n",elapseTime, ig);
|
||||||
|
responseBody.close();
|
||||||
|
//avg
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
httpPost = new HttpPost(get_url);
|
||||||
|
qjson = " {\n" +
|
||||||
|
" \"start\": 1563249700,\n" +
|
||||||
|
" \"queries\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"aggregator\": \"avg\",\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"filters\": [\n"+
|
||||||
|
" {\n" +
|
||||||
|
" \"type\": \"regexp\",\n" +
|
||||||
|
" \"tagk\": \"devgroup\",\n" +
|
||||||
|
" \"filter\": " +"\"" + filter_reg +"\"" + ",\n" +
|
||||||
|
" \"groupby\": false\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }";
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setHeader("Content-type", "application/json");
|
||||||
|
stringEntity = new StringEntity(qjson);
|
||||||
|
httpPost.setEntity(stringEntity);
|
||||||
|
responseBody = httpclient.execute(httpPost);
|
||||||
|
stopTime = System.currentTimeMillis();
|
||||||
|
elapseTime = stopTime - startTime;
|
||||||
|
elapseTime = elapseTime/1000;
|
||||||
|
System.out.printf("Spend %f seconds to avg data when devgroup < %d\n",elapseTime, ig);
|
||||||
|
responseBody.close();
|
||||||
|
//sum
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
httpPost = new HttpPost(get_url);
|
||||||
|
qjson = " {\n" +
|
||||||
|
" \"start\": 1563249700,\n" +
|
||||||
|
" \"queries\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"aggregator\": \"sum\",\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"filters\": [\n"+
|
||||||
|
" {\n" +
|
||||||
|
" \"type\": \"regexp\",\n" +
|
||||||
|
" \"tagk\": \"devgroup\",\n" +
|
||||||
|
" \"filter\": " +"\"" + filter_reg +"\"" +",\n" +
|
||||||
|
" \"groupby\": false\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }";
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setHeader("Content-type", "application/json");
|
||||||
|
stringEntity = new StringEntity(qjson);
|
||||||
|
httpPost.setEntity(stringEntity);
|
||||||
|
responseBody = httpclient.execute(httpPost);
|
||||||
|
stopTime = System.currentTimeMillis();
|
||||||
|
elapseTime = stopTime - startTime;
|
||||||
|
elapseTime = elapseTime/1000;
|
||||||
|
System.out.printf("Spend %f seconds to sum data when devgroup < %d\n",elapseTime, ig);
|
||||||
|
responseBody.close();
|
||||||
|
//max
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
httpPost = new HttpPost(get_url);
|
||||||
|
qjson = " {\n" +
|
||||||
|
" \"start\": 1563249700,\n" +
|
||||||
|
" \"queries\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"aggregator\": \"max\",\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"filters\": [\n"+
|
||||||
|
" {\n" +
|
||||||
|
" \"type\": \"regexp\",\n" +
|
||||||
|
" \"tagk\": \"devgroup\",\n" +
|
||||||
|
" \"filter\": " +"\"" + filter_reg +"\"" + ",\n" +
|
||||||
|
" \"groupby\": false\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }";
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setHeader("Content-type", "application/json");
|
||||||
|
stringEntity = new StringEntity(qjson);
|
||||||
|
httpPost.setEntity(stringEntity);
|
||||||
|
responseBody = httpclient.execute(httpPost);
|
||||||
|
stopTime = System.currentTimeMillis();
|
||||||
|
elapseTime = stopTime - startTime;
|
||||||
|
elapseTime = elapseTime/1000;
|
||||||
|
System.out.printf("Spend %f seconds to max data when devgroup < %d\n",elapseTime, ig);
|
||||||
|
responseBody.close();
|
||||||
|
//min
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
httpPost = new HttpPost(get_url);
|
||||||
|
qjson = " {\n" +
|
||||||
|
" \"start\": 1563249700,\n" +
|
||||||
|
" \"queries\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"aggregator\": \"min\",\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"filters\": [\n"+
|
||||||
|
" {\n" +
|
||||||
|
" \"type\": \"regexp\",\n" +
|
||||||
|
" \"tagk\": \"devgroup\",\n" +
|
||||||
|
" \"filter\": " +"\"" + filter_reg +"\"" + ",\n" +
|
||||||
|
" \"groupby\": false\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }";
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setHeader("Content-type", "application/json");
|
||||||
|
stringEntity = new StringEntity(qjson);
|
||||||
|
httpPost.setEntity(stringEntity);
|
||||||
|
responseBody = httpclient.execute(httpPost);
|
||||||
|
responseBody.close();
|
||||||
|
stopTime = System.currentTimeMillis();
|
||||||
|
elapseTime = stopTime - startTime;
|
||||||
|
elapseTime = elapseTime/1000;
|
||||||
|
System.out.printf("Spend %f seconds to min data when devgroup < %d\n",elapseTime, ig);
|
||||||
|
responseBody.close();
|
||||||
|
break;
|
||||||
|
case "q3":
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
get_url = "http://192.168.1.114:4242/api/query?";
|
||||||
|
httpPost = new HttpPost(get_url);
|
||||||
|
qjson = " {\n" +
|
||||||
|
" \"start\": 1563249700,\n" +
|
||||||
|
" \"queries\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"aggregator\": \"count\",\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"filters\": [\n"+
|
||||||
|
" {\n" +
|
||||||
|
" \"type\": \"regexp\",\n" +
|
||||||
|
" \"tagk\": \"devgroup\",\n" +
|
||||||
|
" \"filter\": " +"\"" + filter_reg +"\"" + ",\n" +
|
||||||
|
" \"groupBy\": true\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" },\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"aggregator\": \"sum\",\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"filters\": [\n"+
|
||||||
|
" {\n" +
|
||||||
|
" \"type\": \"regexp\",\n" +
|
||||||
|
" \"tagk\": \"devgroup\",\n" +
|
||||||
|
" \"filter\": " +"\"" + filter_reg +"\"" + ",\n" +
|
||||||
|
" \"groupBy\": true\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" },\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"aggregator\": \"avg\",\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"filters\": [\n"+
|
||||||
|
" {\n" +
|
||||||
|
" \"type\": \"regexp\",\n" +
|
||||||
|
" \"tagk\": \"devgroup\",\n" +
|
||||||
|
" \"filter\": " +"\"" + filter_reg +"\"" + ",\n" +
|
||||||
|
" \"groupBy\": true\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }";
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setHeader("Content-type", "application/json");
|
||||||
|
stringEntity = new StringEntity(qjson);
|
||||||
|
httpPost.setEntity(stringEntity);
|
||||||
|
responseBody = httpclient.execute(httpPost);
|
||||||
|
/*
|
||||||
|
System.out.println(responseBody.getStatusLine());
|
||||||
|
System.out.println(qjson);
|
||||||
|
*/
|
||||||
|
stopTime = System.currentTimeMillis();
|
||||||
|
elapseTime = stopTime - startTime;
|
||||||
|
elapseTime = elapseTime/1000;
|
||||||
|
System.out.printf("Spend %f seconds to group data by devgroup when devgroup < %d\n",elapseTime, ig);
|
||||||
|
responseBody.close();
|
||||||
|
break;
|
||||||
|
case "q4":
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
get_url = "http://192.168.1.114:4242/api/query?";
|
||||||
|
httpPost = new HttpPost(get_url);
|
||||||
|
qjson = " {\n" +
|
||||||
|
" \"start\": 1563249700,\n" +
|
||||||
|
" \"queries\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"aggregator\": \"none\",\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"filters\": [\n"+
|
||||||
|
" {\n" +
|
||||||
|
" \"type\": \"regexp\",\n" +
|
||||||
|
" \"tagk\": \"devgroup\",\n" +
|
||||||
|
" \"filter\": " +"\"" + filter_reg +"\"" + ",\n" +
|
||||||
|
" \"groupBy\": false\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ],\n" +
|
||||||
|
" \"downsample\": \"1m-sum\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"aggregator\": \"none\",\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"filters\": [\n"+
|
||||||
|
" {\n" +
|
||||||
|
" \"type\": \"regexp\",\n" +
|
||||||
|
" \"tagk\": \"devgroup\",\n" +
|
||||||
|
" \"filter\": " +"\"" + filter_reg +"\"" + ",\n" +
|
||||||
|
" \"groupBy\": false\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ],\n" +
|
||||||
|
" \"downsample\": \"1m-avg\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }";
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setHeader("Content-type", "application/json");
|
||||||
|
stringEntity = new StringEntity(qjson);
|
||||||
|
httpPost.setEntity(stringEntity);
|
||||||
|
responseBody = httpclient.execute(httpPost);
|
||||||
|
/*
|
||||||
|
System.out.println(responseBody.getStatusLine());
|
||||||
|
System.out.println(qjson);
|
||||||
|
*/
|
||||||
|
stopTime = System.currentTimeMillis();
|
||||||
|
elapseTime = stopTime - startTime;
|
||||||
|
elapseTime = elapseTime/1000;
|
||||||
|
System.out.printf("Spend %f seconds to group data by time when devgroup < %d\n",elapseTime, ig);
|
||||||
|
responseBody.close();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
httpclient.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
System.out.println("query end:----\n");
|
||||||
|
} // end write or query
|
||||||
|
System.exit(0);
|
||||||
|
}// end main
|
||||||
|
}// end class
|
|
@ -0,0 +1,155 @@
|
||||||
|
import com.stumbleupon.async.Callback;
|
||||||
|
import com.stumbleupon.async.Deferred;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import net.opentsdb.core.TSDB;
|
||||||
|
import net.opentsdb.uid.NoSuchUniqueName;
|
||||||
|
import net.opentsdb.uid.UniqueId.UniqueIdType;
|
||||||
|
import net.opentsdb.utils.Config;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.concurrent.FutureCallback;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||||
|
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.client.ClientProtocolException;
|
||||||
|
import org.apache.http.client.ResponseHandler;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.apache.http.client.methods.*;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.math.*;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
|
||||||
|
public class WriteThread extends Thread {
|
||||||
|
|
||||||
|
private int[] wargs; // fstart, fend, rows to be read, rows perrequest
|
||||||
|
private String fdir;
|
||||||
|
private int fstart;
|
||||||
|
private int fend;
|
||||||
|
|
||||||
|
public WriteThread (int fstart, int fend,int[] wargs, String fdir) {
|
||||||
|
this.fstart = fstart;
|
||||||
|
this.fend = fend;
|
||||||
|
this.fdir = fdir;
|
||||||
|
this.wargs = wargs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// begin to insert in this thread
|
||||||
|
public void run() {
|
||||||
|
StringEntity stringEntity;
|
||||||
|
String port = "4242";
|
||||||
|
String put_url = "http://192.168.1.114:"+port+"/api/put?summary";
|
||||||
|
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
|
||||||
|
/*
|
||||||
|
httpclient.getHttpConnectionManager().getParams()
|
||||||
|
.setConnectionTimeout(1000);
|
||||||
|
httpclient.getHttpConnectionManager().getParams()
|
||||||
|
.setSoTimeout(5000);
|
||||||
|
*/
|
||||||
|
for (int i=fstart; i<=fend; i++) {
|
||||||
|
String csvfile;
|
||||||
|
csvfile = fdir + "/testdata"+ Integer.toString(i)+".csv";
|
||||||
|
BufferedReader br = null;
|
||||||
|
String line = "";
|
||||||
|
String cvsSplitBy = " ";
|
||||||
|
try {
|
||||||
|
br = new BufferedReader(new FileReader(csvfile));
|
||||||
|
System.out.println("---- begin to read file " +csvfile+"\n");
|
||||||
|
for (int itotalrow =0; itotalrow<wargs[0]; itotalrow=itotalrow+wargs[1]) {
|
||||||
|
HttpPost httpPost = new HttpPost(put_url);
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setHeader("Content-type", "application/json");
|
||||||
|
String totaljson = "[\n";
|
||||||
|
for (int irow =0; irow<wargs[1]; ++irow) {
|
||||||
|
line = br.readLine();
|
||||||
|
if (line !=null) {
|
||||||
|
String[] meter = line.split(cvsSplitBy);
|
||||||
|
// devid, devname,devgroup,ts,temperature,humidity
|
||||||
|
BigInteger timestamp = new BigInteger(meter[3]);
|
||||||
|
timestamp = timestamp.divide(BigInteger.valueOf(1000));
|
||||||
|
long ts = timestamp.longValue();
|
||||||
|
int temperature = Integer.parseInt(meter[4]);
|
||||||
|
float humidity = Float.parseFloat(meter[5]);
|
||||||
|
String onejson = " {\n" +
|
||||||
|
" \"metric\": \"temperature\",\n" +
|
||||||
|
" \"timestamp\": " + String.valueOf(ts) + ",\n" +
|
||||||
|
" \"value\": " + String.valueOf(temperature) + ",\n" +
|
||||||
|
" \"tags\" : {\n" +
|
||||||
|
" \"devid\":" +" \"" + meter[0] + "\",\n" +
|
||||||
|
" \"devname\":" +" \"" + meter[1] + "\",\n" +
|
||||||
|
" \"devgroup\":" +" \"" + meter[2] + "\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
" },\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"metric\": \"humidity\",\n" +
|
||||||
|
" \"timestamp\": " + String.valueOf(ts) + ",\n" +
|
||||||
|
" \"value\": " + String.valueOf(humidity) + ",\n" +
|
||||||
|
" \"tags\" : {\n" +
|
||||||
|
" \"devid\":" +" \"" + meter[0] + "\",\n" +
|
||||||
|
" \"devname\":" +" \"" + meter[1] + "\",\n" +
|
||||||
|
" \"devgroup\":" +" \"" + meter[2] + "\"\n" +
|
||||||
|
" }\n";
|
||||||
|
if (irow == 0) {
|
||||||
|
totaljson = totaljson + onejson;
|
||||||
|
} else if (irow < wargs[1]) {
|
||||||
|
totaljson = totaljson + " },\n" + onejson;
|
||||||
|
}
|
||||||
|
} //end one line reading
|
||||||
|
} //end on batch put
|
||||||
|
totaljson = totaljson + " }\n]";
|
||||||
|
stringEntity = new StringEntity(totaljson);
|
||||||
|
httpPost.setEntity(stringEntity);
|
||||||
|
CloseableHttpResponse responseBody = httpclient.execute(httpPost);
|
||||||
|
/*
|
||||||
|
System.out.println(responseBody.getStatusLine());
|
||||||
|
System.out.println(totaljson);
|
||||||
|
*/
|
||||||
|
responseBody.close();
|
||||||
|
}// end one file reading
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (br != null) {
|
||||||
|
try {
|
||||||
|
br.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//end file iteration
|
||||||
|
httpclient.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.out.println("failed to connect");
|
||||||
|
}
|
||||||
|
}//end run
|
||||||
|
}//end class
|
Binary file not shown.
|
@ -0,0 +1,205 @@
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class TSDBSyncSample {
|
||||||
|
private static final String JDBC_PROTOCAL = "jdbc:TAOS://";
|
||||||
|
private static final String TSDB_DRIVER = "com.taosdata.jdbc.TSDBDriver";
|
||||||
|
|
||||||
|
private String host = "127.0.0.1";
|
||||||
|
private String user = "root";
|
||||||
|
private String password = "taosdata";
|
||||||
|
private int port = 0;
|
||||||
|
private String jdbcUrl = "";
|
||||||
|
|
||||||
|
private String databaseName = "db";
|
||||||
|
private String metricsName = "mt";
|
||||||
|
private String tablePrefix = "t";
|
||||||
|
|
||||||
|
private int tablesCount = 1;
|
||||||
|
private int loopCount = 2;
|
||||||
|
private int batchSize = 10;
|
||||||
|
private long beginTimestamp = 1519833600000L;
|
||||||
|
|
||||||
|
private long rowsInserted = 0;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
Class.forName(TSDB_DRIVER);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
TSDBSyncSample tester = new TSDBSyncSample();
|
||||||
|
tester.doReadArgument(args);
|
||||||
|
|
||||||
|
System.out.println("---------------------------------------------------------------");
|
||||||
|
System.out.println("Start testing...");
|
||||||
|
System.out.println("---------------------------------------------------------------");
|
||||||
|
|
||||||
|
tester.doMakeJdbcUrl();
|
||||||
|
tester.doCreateDbAndTable();
|
||||||
|
tester.doExecuteInsert();
|
||||||
|
tester.doExecuteQuery();
|
||||||
|
|
||||||
|
System.out.println("\n---------------------------------------------------------------");
|
||||||
|
System.out.println("Stop testing...");
|
||||||
|
System.out.println("---------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doReadArgument(String[] args) {
|
||||||
|
System.out.println("Arguments format: host tables loop batchs");
|
||||||
|
if (args.length >= 1) {
|
||||||
|
this.host = args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length >= 2) {
|
||||||
|
this.tablesCount = Integer.parseInt(args[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length >= 3) {
|
||||||
|
this.loopCount = Integer.parseInt(args[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length >= 4) {
|
||||||
|
this.batchSize = Integer.parseInt(args[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doMakeJdbcUrl() {
|
||||||
|
// jdbc:TSDB://127.0.0.1:0/dbname?user=root&password=taosdata
|
||||||
|
System.out.println("\nJDBC URL to use:");
|
||||||
|
this.jdbcUrl = String.format("%s%s:%d/%s?user=%s&password=%s", JDBC_PROTOCAL, this.host, this.port, "",
|
||||||
|
this.user, this.password);
|
||||||
|
System.out.println(this.jdbcUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doCreateDbAndTable() {
|
||||||
|
System.out.println("\n---------------------------------------------------------------");
|
||||||
|
System.out.println("Start creating databases and tables...");
|
||||||
|
String sql = "";
|
||||||
|
try (Connection conn = DriverManager.getConnection(jdbcUrl);
|
||||||
|
Statement stmt = conn.createStatement()){
|
||||||
|
|
||||||
|
sql = "create database if not exists " + this.databaseName;
|
||||||
|
stmt.executeUpdate(sql);
|
||||||
|
System.out.printf("Successfully executed: %s\n", sql);
|
||||||
|
|
||||||
|
sql = "use " + this.databaseName;
|
||||||
|
stmt.executeUpdate(sql);
|
||||||
|
System.out.printf("Successfully executed: %s\n", sql);
|
||||||
|
|
||||||
|
sql = "create table if not exists " + this.metricsName + " (ts timestamp, v1 int) tags(t1 int)";
|
||||||
|
stmt.executeUpdate(sql);
|
||||||
|
System.out.printf("Successfully executed: %s\n", sql);
|
||||||
|
|
||||||
|
for (int i = 0; i < this.tablesCount; i++) {
|
||||||
|
sql = String.format("create table if not exists %s%d using %s tags(%d)", this.tablePrefix, i,
|
||||||
|
this.metricsName, i);
|
||||||
|
stmt.executeUpdate(sql);
|
||||||
|
System.out.printf("Successfully executed: %s\n", sql);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.out.printf("Failed to execute SQL: %s\n", sql);
|
||||||
|
System.exit(4);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(4);
|
||||||
|
}
|
||||||
|
System.out.println("Successfully created databases and tables");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doExecuteInsert() {
|
||||||
|
System.out.println("\n---------------------------------------------------------------");
|
||||||
|
System.out.println("Start inserting data...");
|
||||||
|
int start = (int) System.currentTimeMillis();
|
||||||
|
StringBuilder sql = new StringBuilder("");
|
||||||
|
try (Connection conn = DriverManager.getConnection(jdbcUrl);
|
||||||
|
Statement stmt = conn.createStatement()){
|
||||||
|
stmt.executeUpdate("use " + databaseName);
|
||||||
|
for (int loop = 0; loop < this.loopCount; loop++) {
|
||||||
|
for (int table = 0; table < this.tablesCount; ++table) {
|
||||||
|
sql = new StringBuilder("insert into ");
|
||||||
|
sql.append(this.tablePrefix).append(table).append(" values");
|
||||||
|
for (int batch = 0; batch < this.batchSize; ++batch) {
|
||||||
|
int rows = loop * this.batchSize + batch;
|
||||||
|
sql.append("(").append(this.beginTimestamp + rows).append(",").append(rows).append(")");
|
||||||
|
}
|
||||||
|
int affectRows = stmt.executeUpdate(sql.toString());
|
||||||
|
this.rowsInserted += affectRows;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.out.printf("Failed to execute SQL: %s\n", sql.toString());
|
||||||
|
System.exit(4);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(4);
|
||||||
|
}
|
||||||
|
int end = (int) System.currentTimeMillis();
|
||||||
|
System.out.println("Inserting completed!");
|
||||||
|
System.out.printf("Total %d rows inserted, %d rows failed, time spend %d seconds.\n", this.rowsInserted,
|
||||||
|
this.loopCount * this.batchSize - this.rowsInserted, (end - start) / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doExecuteQuery() {
|
||||||
|
System.out.println("\n---------------------------------------------------------------");
|
||||||
|
System.out.println("Starting querying data...");
|
||||||
|
ResultSet resSet = null;
|
||||||
|
StringBuilder sql = new StringBuilder("");
|
||||||
|
StringBuilder resRow = new StringBuilder("");
|
||||||
|
try (Connection conn = DriverManager.getConnection(jdbcUrl);
|
||||||
|
Statement stmt = conn.createStatement()){
|
||||||
|
stmt.executeUpdate("use " + databaseName);
|
||||||
|
for (int i = 0; i < this.tablesCount; ++i) {
|
||||||
|
sql = new StringBuilder("select * from ").append(this.tablePrefix).append(i);
|
||||||
|
|
||||||
|
resSet = stmt.executeQuery(sql.toString());
|
||||||
|
if (resSet == null) {
|
||||||
|
System.out.println(sql + " failed");
|
||||||
|
System.exit(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultSetMetaData metaData = resSet.getMetaData();
|
||||||
|
System.out.println("Retrieve metadata of " + tablePrefix + i);
|
||||||
|
for (int column = 1; column <= metaData.getColumnCount(); ++column) {
|
||||||
|
System.out.printf("Column%d: name = %s, type = %d, type name = %s, display size = %d\n", column, metaData.getColumnName(column), metaData.getColumnType(column),
|
||||||
|
metaData.getColumnTypeName(column), metaData.getColumnDisplaySize(column));
|
||||||
|
}
|
||||||
|
int rows = 0;
|
||||||
|
System.out.println("Retrieve data of " + tablePrefix + i);
|
||||||
|
while (resSet.next()) {
|
||||||
|
resRow = new StringBuilder();
|
||||||
|
for (int col = 1; col <= metaData.getColumnCount(); col++) {
|
||||||
|
resRow.append(metaData.getColumnName(col)).append("=").append(resSet.getObject(col))
|
||||||
|
.append(" ");
|
||||||
|
}
|
||||||
|
System.out.println(resRow.toString());
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (resSet != null)
|
||||||
|
resSet.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
System.out.printf("Successfully executed query: %s;\nTotal rows returned: %d\n", sql.toString(), rows);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.out.printf("Failed to execute query: %s\n", sql.toString());
|
||||||
|
System.exit(4);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(4);
|
||||||
|
}
|
||||||
|
System.out.println("Query completed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
public static void main( String[] args ) {
|
||||||
|
|
||||||
|
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
|
||||||
|
|
||||||
|
JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
|
||||||
|
|
||||||
|
// create database
|
||||||
|
jdbcTemplate.execute("create database if not exists db ");
|
||||||
|
|
||||||
|
// create table
|
||||||
|
jdbcTemplate.execute("create table if not exists db.tb (ts timestamp, temperature int, humidity float)");
|
||||||
|
|
||||||
|
String insertSql = "insert into db.tb values(now, 23, 10.3) (now + 1s, 20, 9.3)";
|
||||||
|
|
||||||
|
// insert rows
|
||||||
|
int affectedRows = jdbcTemplate.update(insertSql);
|
||||||
|
|
||||||
|
System.out.println("insert success " + affectedRows + " rows.");
|
||||||
|
|
||||||
|
// query for list
|
||||||
|
List<Map<String, Object>> resultList = jdbcTemplate.queryForList("select * from db.tb");
|
||||||
|
|
||||||
|
if(!CollectionUtils.isEmpty(resultList)){
|
||||||
|
for (Map<String, Object> row : resultList){
|
||||||
|
System.out.printf("%s, %d, %s\n", row.get("ts"), row.get("temperature"), row.get("humidity"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||||
|
"
|
||||||
|
default-autowire="byName">
|
||||||
|
|
||||||
|
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||||
|
<property name="driverClassName" value="com.taosdata.jdbc.TSDBDriver"></property>
|
||||||
|
<property name="url" value="jdbc:TAOS://127.0.0.1:6030/log"></property>
|
||||||
|
<property name="username" value="root"></property>
|
||||||
|
<property name="password" value="taosdata"></property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
<bean id = "jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
|
||||||
|
<property name="dataSource" ref = "dataSource" ></property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for simple App.
|
||||||
|
*/
|
||||||
|
public class AppTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Rigorous Test :-)
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void shouldAnswerWithTrue()
|
||||||
|
{
|
||||||
|
assertTrue( true );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.taosdata.jdbc.springbootdemo;
|
||||||
|
|
||||||
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@MapperScan(basePackages = {"com.taosdata.jdbc.springbootdemo.dao"})
|
||||||
|
@SpringBootApplication
|
||||||
|
public class SpringbootdemoApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SpringbootdemoApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.taosdata.jdbc.springbootdemo.controller;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.springbootdemo.domain.Weather;
|
||||||
|
import com.taosdata.jdbc.springbootdemo.service.WeatherService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RequestMapping("/weather")
|
||||||
|
@RestController
|
||||||
|
public class WeatherController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WeatherService weatherService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create database and table
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/init")
|
||||||
|
public boolean init(){
|
||||||
|
return weatherService.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pagination Query
|
||||||
|
* @param limit
|
||||||
|
* @param offset
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/{limit}/{offset}")
|
||||||
|
public List<Weather> queryWeather(@PathVariable Long limit, @PathVariable Long offset){
|
||||||
|
return weatherService.query(limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* upload single weather info
|
||||||
|
* @param temperature
|
||||||
|
* @param humidity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/{temperature}/{humidity}")
|
||||||
|
public int saveWeather(@PathVariable int temperature, @PathVariable float humidity){
|
||||||
|
|
||||||
|
return weatherService.save(temperature, humidity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* upload multi weather info
|
||||||
|
* @param weatherList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/batch")
|
||||||
|
public int batchSaveWeather(@RequestBody List<Weather> weatherList){
|
||||||
|
|
||||||
|
return weatherService.save(weatherList);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.taosdata.jdbc.springbootdemo.dao;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.springbootdemo.domain.Weather;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface WeatherMapper {
|
||||||
|
|
||||||
|
int insert(Weather weather);
|
||||||
|
|
||||||
|
int batchInsert(List<Weather> weatherList);
|
||||||
|
|
||||||
|
List<Weather> select(@Param("limit") Long limit, @Param("offset")Long offset);
|
||||||
|
|
||||||
|
void createDB();
|
||||||
|
|
||||||
|
void createTable();
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.taosdata.jdbc.springbootdemo.domain;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
public class Weather {
|
||||||
|
|
||||||
|
private Timestamp ts;
|
||||||
|
|
||||||
|
private int temperature;
|
||||||
|
|
||||||
|
private float humidity;
|
||||||
|
|
||||||
|
public Timestamp getTs() {
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTs(Timestamp ts) {
|
||||||
|
this.ts = ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTemperature() {
|
||||||
|
return temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTemperature(int temperature) {
|
||||||
|
this.temperature = temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getHumidity() {
|
||||||
|
return humidity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHumidity(float humidity) {
|
||||||
|
this.humidity = humidity;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.taosdata.jdbc.springbootdemo.service;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.springbootdemo.dao.WeatherMapper;
|
||||||
|
import com.taosdata.jdbc.springbootdemo.domain.Weather;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class WeatherService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WeatherMapper weatherMapper;
|
||||||
|
|
||||||
|
public boolean init() {
|
||||||
|
|
||||||
|
weatherMapper.createDB();
|
||||||
|
weatherMapper.createTable();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Weather> query(Long limit, Long offset) {
|
||||||
|
return weatherMapper.select(limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int save(int temperature, float humidity) {
|
||||||
|
Weather weather = new Weather();
|
||||||
|
weather.setTemperature(temperature);
|
||||||
|
weather.setHumidity(humidity);
|
||||||
|
|
||||||
|
return weatherMapper.insert(weather);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int save(List<Weather> weatherList) {
|
||||||
|
return weatherMapper.batchInsert(weatherList);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
# datasource config
|
||||||
|
spring.datasource.driver-class-name=com.taosdata.jdbc.TSDBDriver
|
||||||
|
spring.datasource.url=jdbc:TAOS://127.0.0.1:6030/log
|
||||||
|
spring.datasource.username=root
|
||||||
|
spring.datasource.password=taosdata
|
||||||
|
|
||||||
|
spring.datasource.druid.initial-size=5
|
||||||
|
spring.datasource.druid.min-idle=5
|
||||||
|
spring.datasource.druid.max-active=5
|
||||||
|
# max wait time for get connection, ms
|
||||||
|
spring.datasource.druid.max-wait=60000
|
||||||
|
|
||||||
|
spring.datasource.druid.validation-query=describe log.dn
|
||||||
|
spring.datasource.druid.validation-query-timeout=5000
|
||||||
|
spring.datasource.druid.test-on-borrow=false
|
||||||
|
spring.datasource.druid.test-on-return=false
|
||||||
|
spring.datasource.druid.test-while-idle=true
|
||||||
|
spring.datasource.druid.time-between-eviction-runs-millis=60000
|
||||||
|
spring.datasource.druid.min-evictable-idle-time-millis=600000
|
||||||
|
spring.datasource.druid.max-evictable-idle-time-millis=900000
|
||||||
|
|
||||||
|
|
||||||
|
#mybatis
|
||||||
|
mybatis.mapper-locations=classpath:mapper/*.xml
|
||||||
|
|
||||||
|
logging.level.com.taosdata.jdbc.springbootdemo.dao=debug
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="com.taosdata.jdbc.springbootdemo.dao.WeatherMapper">
|
||||||
|
|
||||||
|
<resultMap id="BaseResultMap" type="com.taosdata.jdbc.springbootdemo.domain.Weather">
|
||||||
|
<id column="ts" jdbcType="TIMESTAMP" property="ts" />
|
||||||
|
<result column="temperature" jdbcType="INTEGER" property="temperature" />
|
||||||
|
<result column="humidity" jdbcType="FLOAT" property="humidity" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<update id="createDB" >
|
||||||
|
create database if not exists test;
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="createTable" >
|
||||||
|
create table if not exists test.weather(ts timestamp, temperature int, humidity float);
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
ts, temperature, humidity
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="select" resultMap="BaseResultMap">
|
||||||
|
select
|
||||||
|
<include refid="Base_Column_List" />
|
||||||
|
from test.weather
|
||||||
|
order by ts desc
|
||||||
|
<if test="limit != null">
|
||||||
|
limit #{limit,jdbcType=BIGINT}
|
||||||
|
</if>
|
||||||
|
<if test="offset != null">
|
||||||
|
offset #{offset,jdbcType=BIGINT}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insert" parameterType="com.taosdata.jdbc.springbootdemo.domain.Weather" >
|
||||||
|
insert into test.weather (ts, temperature, humidity) values (now, #{temperature,jdbcType=INTEGER}, #{humidity,jdbcType=FLOAT})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<insert id="batchInsert" parameterType="java.util.List" >
|
||||||
|
insert into test.weather (ts, temperature, humidity) values
|
||||||
|
<foreach separator=" " collection="list" item="weather" index="index" >
|
||||||
|
(now + #{index}a, #{weather.temperature}, #{weather.humidity})
|
||||||
|
</foreach>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
|
||||||
|
</mapper>
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.taosdata.jdbc.springbootdemo;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class SpringbootdemoApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue