Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
dd9228e0
T
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
dd9228e0
编写于
11月 23, 2020
作者:
Z
zyyang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[TD-1859]<feature>: restful implementation for taos-jdbc
上级
4c11e460
变更
9
显示空白变更内容
内联
并排
Showing
9 changed file
with
263 addition
and
51 deletion
+263
-51
src/connector/jdbc/deploy-pom.xml
src/connector/jdbc/deploy-pom.xml
+1
-1
src/connector/jdbc/pom.xml
src/connector/jdbc/pom.xml
+8
-1
src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java
...src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java
+28
-13
src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java
...dbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java
+1
-1
src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulStatement.java
.../src/main/java/com/taosdata/jdbc/rs/RestfulStatement.java
+60
-11
src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/SqlSyntaxValidator.java
...main/java/com/taosdata/jdbc/utils/SqlSyntaxValidator.java
+28
-1
src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDriverTest.java
...src/test/java/com/taosdata/jdbc/rs/RestfulDriverTest.java
+0
-23
src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java
...c/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java
+108
-0
src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/SqlSyntaxValidatorTest.java
.../java/com/taosdata/jdbc/utils/SqlSyntaxValidatorTest.java
+29
-0
未找到文件。
src/connector/jdbc/deploy-pom.xml
浏览文件 @
dd9228e0
...
...
@@ -5,7 +5,7 @@
<groupId>
com.taosdata.jdbc
</groupId>
<artifactId>
taos-jdbcdriver
</artifactId>
<version>
2.0.1
0
</version>
<version>
2.0.1
3
</version>
<packaging>
jar
</packaging>
<name>
JDBCDriver
</name>
...
...
src/connector/jdbc/pom.xml
浏览文件 @
dd9228e0
...
...
@@ -3,7 +3,7 @@
<modelVersion>
4.0.0
</modelVersion>
<groupId>
com.taosdata.jdbc
</groupId>
<artifactId>
taos-jdbcdriver
</artifactId>
<version>
2.0.
8
</version>
<version>
2.0.
13
</version>
<packaging>
jar
</packaging>
<name>
JDBCDriver
</name>
<url>
https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc
</url>
...
...
@@ -112,6 +112,13 @@
<artifactId>
maven-surefire-plugin
</artifactId>
<version>
2.12.4
</version>
<configuration>
<includes>
<include>
**/*Test.java
</include>
</includes>
<excludes>
<exclude>
**/BatchInsertTest.java
</exclude>
<exclude>
**/FailOverTest.java
</exclude>
</excludes>
<testFailureIgnore>
true
</testFailureIgnore>
</configuration>
</plugin>
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java
浏览文件 @
dd9228e0
...
...
@@ -15,7 +15,6 @@ public class RestfulConnection implements Connection {
private
final
String
database
;
private
final
String
url
;
public
RestfulConnection
(
String
host
,
String
port
,
Properties
props
,
String
database
,
String
url
)
{
this
.
host
=
host
;
this
.
port
=
Integer
.
parseInt
(
port
);
...
...
@@ -28,7 +27,7 @@ public class RestfulConnection implements Connection {
public
Statement
createStatement
()
throws
SQLException
{
if
(
isClosed
())
throw
new
SQLException
(
TSDBConstants
.
WrapErrMsg
(
"restful TDengine connection is closed."
));
return
new
RestfulStatement
(
this
,
this
.
database
);
return
new
RestfulStatement
(
this
,
database
);
}
@Override
...
...
@@ -104,22 +103,28 @@ public class RestfulConnection implements Connection {
@Override
public
void
setTransactionIsolation
(
int
level
)
throws
SQLException
{
//transaction is not supported
throw
new
SQLFeatureNotSupportedException
(
"transactions are not supported"
);
}
/**
*
*/
@Override
public
int
getTransactionIsolation
()
throws
SQLException
{
return
0
;
//Connection.TRANSACTION_NONE specifies that transactions are not supported.
return
Connection
.
TRANSACTION_NONE
;
}
@Override
public
SQLWarning
getWarnings
()
throws
SQLException
{
//TODO: getWarnings not implemented
return
null
;
}
@Override
public
void
clearWarnings
()
throws
SQLException
{
throw
new
SQLFeatureNotSupportedException
(
"clearWarnings not supported."
);
}
@Override
...
...
@@ -209,22 +214,26 @@ public class RestfulConnection implements Connection {
@Override
public
Clob
createClob
()
throws
SQLException
{
return
null
;
//TODO: not supported
throw
new
SQLFeatureNotSupportedException
();
}
@Override
public
Blob
createBlob
()
throws
SQLException
{
return
null
;
//TODO: not supported
throw
new
SQLFeatureNotSupportedException
();
}
@Override
public
NClob
createNClob
()
throws
SQLException
{
return
null
;
//TODO: not supported
throw
new
SQLFeatureNotSupportedException
();
}
@Override
public
SQLXML
createSQLXML
()
throws
SQLException
{
return
null
;
//TODO: not supported
throw
new
SQLFeatureNotSupportedException
();
}
@Override
...
...
@@ -254,12 +263,14 @@ public class RestfulConnection implements Connection {
@Override
public
Array
createArrayOf
(
String
typeName
,
Object
[]
elements
)
throws
SQLException
{
return
null
;
//TODO: not supported
throw
new
SQLFeatureNotSupportedException
();
}
@Override
public
Struct
createStruct
(
String
typeName
,
Object
[]
attributes
)
throws
SQLException
{
return
null
;
//TODO: not supported
throw
new
SQLFeatureNotSupportedException
();
}
@Override
...
...
@@ -289,12 +300,16 @@ public class RestfulConnection implements Connection {
@Override
public
<
T
>
T
unwrap
(
Class
<
T
>
iface
)
throws
SQLException
{
return
null
;
try
{
return
iface
.
cast
(
this
);
}
catch
(
ClassCastException
cce
)
{
throw
new
SQLException
(
"Unable to unwrap to "
+
iface
.
toString
());
}
}
@Override
public
boolean
isWrapperFor
(
Class
<?>
iface
)
throws
SQLException
{
return
false
;
return
iface
.
isInstance
(
this
)
;
}
public
String
getHost
()
{
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java
浏览文件 @
dd9228e0
...
...
@@ -35,7 +35,7 @@ public class RestfulDriver extends AbstractTaosDriver {
Properties
props
=
parseURL
(
url
,
info
);
String
host
=
props
.
getProperty
(
TSDBDriver
.
PROPERTY_KEY_HOST
,
"localhost"
);
String
port
=
props
.
getProperty
(
TSDBDriver
.
PROPERTY_KEY_PORT
,
"6041"
);
String
database
=
props
.
getProperty
(
TSDBDriver
.
PROPERTY_KEY_DBNAME
)
;
String
database
=
props
.
containsKey
(
TSDBDriver
.
PROPERTY_KEY_DBNAME
)
?
props
.
getProperty
(
TSDBDriver
.
PROPERTY_KEY_DBNAME
)
:
null
;
String
loginUrl
=
"http://"
+
props
.
getProperty
(
TSDBDriver
.
PROPERTY_KEY_HOST
)
+
":"
+
props
.
getProperty
(
TSDBDriver
.
PROPERTY_KEY_PORT
)
+
"/rest/login/"
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulStatement.java
浏览文件 @
dd9228e0
...
...
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import
com.alibaba.fastjson.JSONObject
;
import
com.taosdata.jdbc.TSDBConstants
;
import
com.taosdata.jdbc.rs.util.HttpClientPoolUtil
;
import
com.taosdata.jdbc.utils.SqlSyntaxValidator
;
import
java.sql.*
;
import
java.util.Arrays
;
...
...
@@ -11,19 +12,23 @@ import java.util.List;
public
class
RestfulStatement
implements
Statement
{
private
final
String
catalog
;
private
boolean
closed
;
private
String
database
;
private
final
RestfulConnection
conn
;
public
RestfulStatement
(
RestfulConnection
c
,
String
catalog
)
{
public
RestfulStatement
(
RestfulConnection
c
,
String
database
)
{
this
.
conn
=
c
;
this
.
catalog
=
catalog
;
this
.
database
=
database
;
}
@Override
public
ResultSet
executeQuery
(
String
sql
)
throws
SQLException
{
if
(
isClosed
())
throw
new
SQLException
(
"statement already closed"
);
if
(!
SqlSyntaxValidator
.
isSelectSql
(
sql
))
throw
new
SQLException
(
"not a select sql for executeQuery: "
+
sql
);
final
String
url
=
"http://"
+
conn
.
getHost
()
+
":"
+
conn
.
getPort
()+
"/rest/sql"
;
final
String
url
=
"http://"
+
conn
.
getHost
()
+
":"
+
conn
.
getPort
()
+
"/rest/sql"
;
String
result
=
HttpClientPoolUtil
.
execute
(
url
,
sql
);
String
fields
=
""
;
List
<
String
>
words
=
Arrays
.
asList
(
sql
.
split
(
" "
));
...
...
@@ -65,12 +70,29 @@ public class RestfulStatement implements Statement {
@Override
public
int
executeUpdate
(
String
sql
)
throws
SQLException
{
return
0
;
if
(
isClosed
())
throw
new
SQLException
(
"statement already closed"
);
if
(!
SqlSyntaxValidator
.
isValidForExecuteUpdate
(
sql
))
throw
new
SQLException
(
"not a valid sql for executeUpdate: "
+
sql
);
if
(
this
.
database
==
null
)
throw
new
SQLException
(
"Database not specified or available"
);
final
String
url
=
"http://"
+
conn
.
getHost
()
+
":"
+
conn
.
getPort
()
+
"/rest/sql"
;
HttpClientPoolUtil
.
execute
(
url
,
"use "
+
conn
.
getDatabase
());
String
result
=
HttpClientPoolUtil
.
execute
(
url
,
sql
);
JSONObject
jsonObject
=
JSON
.
parseObject
(
result
);
if
(
jsonObject
.
getString
(
"status"
).
equals
(
"error"
))
{
throw
new
SQLException
(
TSDBConstants
.
WrapErrMsg
(
"SQL execution error: "
+
jsonObject
.
getString
(
"desc"
)
+
"\n"
+
"error code: "
+
jsonObject
.
getString
(
"code"
)));
}
return
Integer
.
parseInt
(
jsonObject
.
getString
(
"rows"
));
}
@Override
public
void
close
()
throws
SQLException
{
this
.
closed
=
true
;
}
@Override
...
...
@@ -115,6 +137,7 @@ public class RestfulStatement implements Statement {
@Override
public
SQLWarning
getWarnings
()
throws
SQLException
{
//TODO: getWarnings not Implemented
return
null
;
}
...
...
@@ -130,7 +153,29 @@ public class RestfulStatement implements Statement {
@Override
public
boolean
execute
(
String
sql
)
throws
SQLException
{
return
false
;
if
(
isClosed
())
{
throw
new
SQLException
(
"Invalid method call on a closed statement."
);
}
//如果执行了use操作应该将当前Statement的catalog设置为新的database
if
(
SqlSyntaxValidator
.
isUseSql
(
sql
))
{
this
.
database
=
sql
.
trim
().
replace
(
"use"
,
""
).
trim
();
}
if
(
this
.
database
==
null
)
throw
new
SQLException
(
"Database not specified or available"
);
final
String
url
=
"http://"
+
conn
.
getHost
()
+
":"
+
conn
.
getPort
()
+
"/rest/sql"
;
// use database
HttpClientPoolUtil
.
execute
(
url
,
"use "
+
conn
.
getDatabase
());
// execute sql
String
result
=
HttpClientPoolUtil
.
execute
(
url
,
sql
);
// parse result
JSONObject
jsonObject
=
JSON
.
parseObject
(
result
);
if
(
jsonObject
.
getString
(
"status"
).
equals
(
"error"
))
{
throw
new
SQLException
(
TSDBConstants
.
WrapErrMsg
(
"SQL execution error: "
+
jsonObject
.
getString
(
"desc"
)
+
"\n"
+
"error code: "
+
jsonObject
.
getString
(
"code"
)));
}
return
true
;
}
@Override
...
...
@@ -245,7 +290,7 @@ public class RestfulStatement implements Statement {
@Override
public
boolean
isClosed
()
throws
SQLException
{
return
false
;
return
closed
;
}
@Override
...
...
@@ -270,11 +315,15 @@ public class RestfulStatement implements Statement {
@Override
public
<
T
>
T
unwrap
(
Class
<
T
>
iface
)
throws
SQLException
{
return
null
;
try
{
return
iface
.
cast
(
this
);
}
catch
(
ClassCastException
cce
)
{
throw
new
SQLException
(
"Unable to unwrap to "
+
iface
.
toString
());
}
}
@Override
public
boolean
isWrapperFor
(
Class
<?>
iface
)
throws
SQLException
{
return
false
;
return
iface
.
isInstance
(
this
)
;
}
}
src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/SqlSyntaxValidator.java
浏览文件 @
dd9228e0
...
...
@@ -22,6 +22,9 @@ import java.sql.SQLException;
public
class
SqlSyntaxValidator
{
private
static
final
String
[]
updateSQL
=
{
"insert"
,
"update"
,
"delete"
,
"create"
,
"alter"
,
"drop"
,
"show"
,
"describe"
,
"use"
};
private
static
final
String
[]
querySQL
=
{
"select"
};
private
TSDBConnection
tsdbConnection
;
public
SqlSyntaxValidator
(
Connection
connection
)
{
...
...
@@ -43,4 +46,28 @@ public class SqlSyntaxValidator {
}
return
res
;
}
public
static
boolean
isValidForExecuteUpdate
(
String
sql
)
{
for
(
String
prefix
:
updateSQL
)
{
if
(
sql
.
trim
().
toLowerCase
().
startsWith
(
prefix
))
return
true
;
}
return
false
;
}
public
static
boolean
isUseSql
(
String
sql
)
{
return
sql
.
trim
().
toLowerCase
().
startsWith
(
updateSQL
[
8
])
||
sql
.
trim
().
toLowerCase
().
matches
(
"create\\s*database.*"
)
||
sql
.
toLowerCase
().
toLowerCase
().
matches
(
"drop\\s*database.*"
);
}
public
static
boolean
isUpdateSql
(
String
sql
)
{
return
sql
.
trim
().
toLowerCase
().
startsWith
(
updateSQL
[
1
]);
}
public
static
boolean
isInsertSql
(
String
sql
)
{
return
sql
.
trim
().
toLowerCase
().
startsWith
(
updateSQL
[
0
]);
}
public
static
boolean
isSelectSql
(
String
sql
)
{
return
sql
.
trim
().
toLowerCase
().
startsWith
(
querySQL
[
0
]);
}
}
src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDriverTest.java
浏览文件 @
dd9228e0
...
...
@@ -7,29 +7,6 @@ import java.sql.*;
public
class
RestfulDriverTest
{
@Test
public
void
testCase001
()
{
try
{
Class
.
forName
(
"com.taosdata.jdbc.rs.RestfulDriver"
);
Connection
connection
=
DriverManager
.
getConnection
(
"jdbc:TAOS-RS://master:6041/?user=root&password=taosdata"
);
Statement
statement
=
connection
.
createStatement
();
ResultSet
resultSet
=
statement
.
executeQuery
(
"select * from log.log"
);
ResultSetMetaData
metaData
=
resultSet
.
getMetaData
();
while
(
resultSet
.
next
())
{
for
(
int
i
=
1
;
i
<=
metaData
.
getColumnCount
();
i
++)
{
String
column
=
metaData
.
getColumnLabel
(
i
);
String
value
=
resultSet
.
getString
(
i
);
System
.
out
.
print
(
column
+
":"
+
value
+
"\t"
);
}
System
.
out
.
println
();
}
statement
.
close
();
connection
.
close
();
}
catch
(
SQLException
|
ClassNotFoundException
e
)
{
e
.
printStackTrace
();
}
}
@Test
public
void
connect
()
{
...
...
src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java
0 → 100644
浏览文件 @
dd9228e0
package
com.taosdata.jdbc.rs
;
import
org.junit.*
;
import
org.junit.runners.MethodSorters
;
import
java.sql.*
;
import
java.util.Random
;
@FixMethodOrder
(
MethodSorters
.
NAME_ASCENDING
)
public
class
RestfulJDBCTest
{
private
Connection
connection
;
@Before
public
void
before
()
throws
ClassNotFoundException
,
SQLException
{
Class
.
forName
(
"com.taosdata.jdbc.rs.RestfulDriver"
);
connection
=
DriverManager
.
getConnection
(
"jdbc:TAOS-RS://master:6041/restful_test?user=root&password=taosdata"
);
}
@After
public
void
after
()
throws
SQLException
{
if
(
connection
!=
null
)
connection
.
close
();
}
/**
* 查询所有log.log
**/
@Test
public
void
testCase001
()
{
try
{
Statement
statement
=
connection
.
createStatement
();
ResultSet
resultSet
=
statement
.
executeQuery
(
"select * from log.log"
);
ResultSetMetaData
metaData
=
resultSet
.
getMetaData
();
while
(
resultSet
.
next
())
{
for
(
int
i
=
1
;
i
<=
metaData
.
getColumnCount
();
i
++)
{
String
column
=
metaData
.
getColumnLabel
(
i
);
String
value
=
resultSet
.
getString
(
i
);
System
.
out
.
print
(
column
+
":"
+
value
+
"\t"
);
}
System
.
out
.
println
();
}
statement
.
close
();
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
}
}
/**
* create database
*/
@Test
public
void
testCase002
()
{
try
(
Statement
stmt
=
connection
.
createStatement
())
{
stmt
.
execute
(
"drop database if exists restful_test"
);
stmt
.
execute
(
"create database if not exists restful_test"
);
stmt
.
execute
(
"use restful_test"
);
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
}
}
/**
* create super table
***/
@Test
public
void
testCase003
()
{
try
(
Statement
stmt
=
connection
.
createStatement
())
{
stmt
.
execute
(
"create table weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)"
);
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
}
}
@Test
public
void
testCase004
()
{
try
(
Statement
stmt
=
connection
.
createStatement
())
{
for
(
int
i
=
1
;
i
<=
100
;
i
++)
{
stmt
.
execute
(
"create table t"
+
i
+
" using weather tags('beijing', '"
+
i
+
"')"
);
}
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
}
}
private
Random
random
=
new
Random
(
System
.
currentTimeMillis
());
@Test
public
void
testCase005
()
{
try
(
Statement
stmt
=
connection
.
createStatement
())
{
int
rows
=
0
;
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
for
(
int
j
=
1
;
j
<=
100
;
j
++)
{
long
currentTimeMillis
=
System
.
currentTimeMillis
();
int
affectRows
=
stmt
.
executeUpdate
(
"insert into t"
+
j
+
" values("
+
currentTimeMillis
+
","
+
(
random
.
nextFloat
()
*
50
)
+
","
+
random
.
nextInt
(
100
)
+
")"
);
Assert
.
assertEquals
(
1
,
affectRows
);
rows
+=
affectRows
;
}
}
Assert
.
assertEquals
(
1000
,
rows
);
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
}
}
}
src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/SqlSyntaxValidatorTest.java
0 → 100644
浏览文件 @
dd9228e0
package
com.taosdata.jdbc.utils
;
import
com.sun.source.tree.AssertTree
;
import
org.junit.Assert
;
import
org.junit.Test
;
public
class
SqlSyntaxValidatorTest
{
@Test
public
void
validateSqlSyntax
()
{
}
@Test
public
void
isSelectSQL
()
{
Assert
.
assertTrue
(
SqlSyntaxValidator
.
isSelectSql
(
"select * from test.weather"
));
Assert
.
assertTrue
(
SqlSyntaxValidator
.
isSelectSql
(
" select * from test.weather"
));
Assert
.
assertTrue
(
SqlSyntaxValidator
.
isSelectSql
(
" select * from test.weather "
));
Assert
.
assertFalse
(
SqlSyntaxValidator
.
isSelectSql
(
"insert into test.weather values(now, 1.1, 2)"
));
}
@Test
public
void
isUseSQL
()
{
Assert
.
assertTrue
(
SqlSyntaxValidator
.
isUseSql
(
"use database test"
));
Assert
.
assertTrue
(
SqlSyntaxValidator
.
isUseSql
(
"create database test"
));
Assert
.
assertTrue
(
SqlSyntaxValidator
.
isUseSql
(
"create database if not exist test"
));
Assert
.
assertTrue
(
SqlSyntaxValidator
.
isUseSql
(
"drop database test"
));
Assert
.
assertTrue
(
SqlSyntaxValidator
.
isUseSql
(
"drop database if exist test"
));
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录