Skip to content

Commit 5f438f2

Browse files
committed
Java:MultiDataSource 新增支持 Apache/IoTDB - 一体化收集、存储、管理与分析物联网时序数据的软件系统
1 parent 20ee768 commit 5f438f2

File tree

6 files changed

+154
-34
lines changed

6 files changed

+154
-34
lines changed

APIJSON-Java-Server/APIJSONBoot-MultiDataSource/pom.xml

+10
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@
7676
<artifactId>apijson-router</artifactId>
7777
<version>2.0.3</version>
7878
</dependency>
79+
<dependency>
80+
<groupId>org.apache.iotdb</groupId>
81+
<artifactId>iotdb-jdbc</artifactId>
82+
<version>1.3.1</version>
83+
</dependency>
84+
<dependency>
85+
<groupId>org.apache.iotdb</groupId>
86+
<artifactId>iotdb-session</artifactId>
87+
<version>1.3.1</version>
88+
</dependency>
7989
<!-- <dependency>-->
8090
<!-- <groupId>com.github.APIJSON</groupId>-->
8191
<!-- <artifactId>apijson-milvus</artifactId>-->

APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/DemoApplication.java

+10
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,16 @@ public void addCorsMappings(CorsRegistry registry) {
194194
Log.e(TAG, "加载 Databricks 驱动失败,请检查 pom.xml 中 com.databricks 版本是否存在以及可用 !!!");
195195
}
196196

197+
try { //加载驱动程序
198+
Log.d(TAG, "尝试加载 IoTDB 驱动 <<<<<<<<<<<<<<<<<<<<< ");
199+
Class.forName("org.apache.iotdb.jdbc.IoTDBDriver");
200+
Log.d(TAG, "成功加载 IoTDB 驱动!>>>>>>>>>>>>>>>>>>>>> ");
201+
}
202+
catch (ClassNotFoundException e) {
203+
e.printStackTrace();
204+
Log.e(TAG, "加载 IoTDB 驱动失败,请检查 pom.xml 中 org.apache.iotdb.jdbc 版本是否存在以及可用 !!!");
205+
}
206+
197207
// try { //加载驱动程序
198208
// Log.d(TAG, "尝试加载 TDengine 驱动 <<<<<<<<<<<<<<<<<<<<< ");
199209
// Class.forName("com.taosdata.jdbc.TSDBDriver");

APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLConfig.java

+25-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public DemoSQLConfig(RequestMethod method, String table) {
5454
// 支持 NoSQL 数据库 MongoDB,APIJSON 6.4.0- 版本需要手动添加相关代码 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
5555
public static final String DATABASE_MONGODB = "MONGODB";
5656
public static final String DATABASE_MILVUS = "MILVUS";
57+
public static final String DATABASE_IOTDB = "IOTDB";
5758

5859
@Override
5960
public boolean isPrepared() {
@@ -67,11 +68,14 @@ public boolean isMongoDB() {
6768
public boolean isMilvus() {
6869
return DATABASE_MILVUS.equals(getDatabase());
6970
}
71+
public boolean isIoTDB() {
72+
return DATABASE_IOTDB.equals(getDatabase());
73+
}
7074

7175
// MongoDB 同时支持 `tbl` 反引号 和 "col" 双引号
7276
@Override
7377
public String getQuote() {
74-
return isMilvus() ? "`" : super.getQuote();
78+
return isMilvus() ? "`" : (isIoTDB() ? "" : super.getQuote());
7579
}
7680

7781
@Override
@@ -94,6 +98,7 @@ public String getLimitString() {
9498
DATABASE_LIST.add(DATABASE_MONGODB);
9599
DATABASE_LIST.add(DATABASE_MILVUS);
96100
DATABASE_LIST.add(DATABASE_CASSANDRA);
101+
DATABASE_LIST.add(DATABASE_IOTDB);
97102

98103
// Milvus 需要
99104
SQL_FUNCTION_MAP.put("vMatch", "");
@@ -227,6 +232,9 @@ public String getDBVersion() {
227232
if (isMilvus()) {
228233
return "2.3.4"; //TODO 改成你自己的
229234
}
235+
if (isIoTDB()) {
236+
return "1.3.1"; //TODO 改成你自己的
237+
}
230238
if (isMongoDB()) {
231239
return "6.0.12"; //TODO 改成你自己的
232240
}
@@ -283,6 +291,9 @@ public String getDBUri() {
283291
if (isMilvus()) {
284292
return "http://localhost:19530";
285293
}
294+
if (isIoTDB()) {
295+
return "jdbc:iotdb://127.0.0.1:6667?charset=GB18030";
296+
}
286297
if (isMongoDB()) {
287298
return "jdbc:mongodb://atlas-sql-6593c65c296c5865121e6ebe-xxskv.a.query.mongodb.net/myVirtualDatabase?ssl=true&authSource=admin";
288299
}
@@ -335,6 +346,9 @@ public String getDBAccount() {
335346
if (isMilvus()) {
336347
return "root";
337348
}
349+
if (isIoTDB()) {
350+
return "root";
351+
}
338352
if (isMongoDB()) {
339353
return "root"; //TODO 改成你自己的
340354
}
@@ -387,6 +401,9 @@ public String getDBPassword() {
387401
if (isMilvus()) {
388402
return "apijson"; //TODO 改成你自己的
389403
}
404+
if (isIoTDB()) {
405+
return "root";
406+
}
390407
if (isMongoDB()) {
391408
return "apijson"; //TODO 改成你自己的
392409
}
@@ -512,10 +529,16 @@ protected int getMaxCombineCount() {
512529
@Override
513530
public String getSQLTable() {
514531
String t = super.getSQLTable();
515-
return isInfluxDB() ? t.toLowerCase() : t;
532+
return isInfluxDB() || isIoTDB() ? t.toLowerCase() : t;
516533
// return isInfluxDB() ? t.toLowerCase() : StringUtil.firstCase(JSONRequest.recoverUnderline(t, false), false);
517534
}
518535

536+
@Override
537+
public String getTablePath() {
538+
String p = super.getTablePath();
539+
return isIoTDB() ? p + ".**" : p;
540+
}
541+
519542
// 取消注释可将前端传参驼峰命名转为蛇形命名 aBCdEfg => upper ? A_B_CD_EFG : a_b_cd_efg
520543
// @Override
521544
// public String getSQLKey(String key) {

APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLExecutor.java

+67-5
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414

1515
package apijson.demo;
1616

17-
import apijson.JSON;
18-
import apijson.Log;
19-
import apijson.NotNull;
20-
import apijson.RequestMethod;
17+
import apijson.*;
2118
import apijson.boot.DemoApplication;
2219
//import apijson.cassandra.CassandraUtil;
2320
import apijson.framework.APIJSONSQLExecutor;
@@ -27,6 +24,10 @@
2724
import apijson.orm.SQLConfig;
2825
import com.alibaba.druid.pool.DruidDataSource;
2926
import com.alibaba.fastjson.JSONObject;
27+
import org.apache.iotdb.isession.SessionDataSet;
28+
import org.apache.iotdb.session.Session;
29+
import org.apache.iotdb.tsfile.read.common.Field;
30+
import org.apache.iotdb.tsfile.read.common.RowRecord;
3031
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
3132
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
3233
import org.springframework.data.redis.core.RedisTemplate;
@@ -39,6 +40,7 @@
3940
import java.sql.ResultSet;
4041
import java.sql.ResultSetMetaData;
4142
import java.util.ArrayList;
43+
import java.util.Collection;
4244
import java.util.List;
4345
import java.util.Map;
4446
import java.util.concurrent.TimeUnit;
@@ -196,8 +198,9 @@ public JSONObject execute(@NotNull SQLConfig<Long> config, boolean unknownType)
196198
boolean isMilvus = DATABASE_MILVUS.equals(config.getDatabase()); // APIJSON 6.4.0+ 可用 config.isMilvus();
197199
boolean isCassandra = config.isCassandra();
198200
boolean isInfluxDB = config.isInfluxDB();
201+
boolean isIoTDB = DemoSQLConfig.DATABASE_IOTDB.equals(config.getDatabase());
199202

200-
if (isMilvus || isCassandra || isInfluxDB) {
203+
if (isMilvus || isCassandra || isInfluxDB || isIoTDB) {
201204
// TODO 把 execute 内与缓存无关只与数据库读写逻辑相关的代码抽取到 executeSQL 函数
202205
String sql = config.getSQL(false); // config.isPrepared());
203206
if (sql != null && config.getMethod() == null) {
@@ -250,6 +253,65 @@ else if (sqlPrefix.startsWith("DELETE ")) {
250253
//
251254
// resultList = InfluxDBUtil.executeQuery(config, sql, unknownType);
252255
// }
256+
// else
257+
if (isIoTDB) {
258+
Session session = new Session.Builder()
259+
.username(config.getDBAccount())
260+
.password(config.getDBPassword())
261+
.build();
262+
session.open();
263+
264+
if (isWrite) {
265+
session.executeNonQueryStatement(sql);
266+
267+
Object id = config.getId();
268+
Object idIn = id != null ? null : config.getIdIn();
269+
Collection<?> ids = idIn instanceof Collection<?> ? (Collection<?>) idIn : null;
270+
int count = id != null ? 1 : (ids == null || ids.isEmpty() ? 1 : ids.size());
271+
272+
result = DemoParser.newSuccessResult();
273+
result.put(JSONResponse.KEY_COUNT, 1);
274+
result.put(JSONResponse.KEY_OK, true);
275+
276+
session.close();
277+
278+
return result;
279+
}
280+
281+
SessionDataSet ds = session.executeQueryStatement(sql);
282+
List<String> ns = ds == null ? null : ds.getColumnNames();
283+
List<String> nameList = ns == null || ns.isEmpty() ? null : new ArrayList<>(ns.size());
284+
if (nameList != null) {
285+
String prefix = config.getSQLSchema() + "." + config.getSQLTable() + ".";
286+
287+
for (String name : ns) {
288+
if (name.startsWith(prefix)) {
289+
name = name.substring(prefix.length());
290+
}
291+
292+
nameList.add(name);
293+
}
294+
295+
resultList = new ArrayList<>(ds.getFetchSize());
296+
297+
while (ds.hasNext()) {
298+
RowRecord row = ds.next();
299+
List<Field> fs = row.getFields();
300+
301+
JSONObject obj = new JSONObject(true);
302+
obj.put(nameList.get(0), row.getTimestamp());
303+
for (int i = 0; i < fs.size(); i++) {
304+
Field f = fs.get(i);
305+
Object v = f == null ? null : f.getObjectValue(f.getDataType());
306+
obj.put(nameList.get(i + 1), v);
307+
}
308+
309+
resultList.add(obj);
310+
}
311+
}
312+
313+
session.close();
314+
}
253315

254316
// TODO 把 execute 内与缓存无关只与数据库读写逻辑相关的代码抽取到 executeSQL 函数
255317
result = resultList.isEmpty() ? new JSONObject() : resultList.get(0);

APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/JSONResponse.js

+30-19
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,9 @@ var JSONResponse = {
531531
3-对象缺少字段/整数变小数,黄色;
532532
4-code/值类型 改变,红色;
533533
*/
534-
compareResponse: function(res, target, real, folder, isMachineLearning, codeName, exceptKeys, ignoreTrend) {
535-
var tStatus = (target || {}).status || 200;
534+
compareResponse: function(res, target, real, folder, isMachineLearning, codeName, exceptKeys, ignoreTrend, noBizCode) {
535+
target = target || {}
536+
var tStatus = target.status || 200;
536537
var rStatus = (res || {}).status;
537538
if (rStatus != null && rStatus != tStatus) {
538539
return {
@@ -542,8 +543,8 @@ var JSONResponse = {
542543
}
543544
}
544545
codeName = StringUtil.isEmpty(codeName, true) ? JSONResponse.KEY_CODE : codeName;
545-
var tCode = (target || {})[codeName];
546-
var rCode = (real || {})[codeName];
546+
var tCode = (isMachineLearning != true && noBizCode) ? 0 : (target || {})[codeName];
547+
var rCode = noBizCode ? tCode : (real || {})[codeName];
547548

548549
//解决了弹窗提示机器学习更新标准异常,但导致所有项测试结果都变成状态码 code 改变
549550
// if (real == null) {
@@ -587,7 +588,7 @@ var JSONResponse = {
587588
}
588589

589590
var tThrw = target.throw;
590-
var rThrw = real.throw;
591+
var rThrw = noBizCode ? tThrw : real.throw;
591592

592593
var exceptions = target.exceptions || [];
593594
if (rCode != tCode || rThrw != tThrw) {
@@ -620,11 +621,12 @@ var JSONResponse = {
620621
};
621622
}
622623

623-
delete target[codeName];
624-
delete real[codeName];
625-
626-
delete target.throw;
627-
delete real.throw;
624+
if (noBizCode != true) {
625+
delete target[codeName];
626+
delete real[codeName];
627+
delete target.throw;
628+
delete real.throw;
629+
}
628630

629631
//可能提示语变化,也要提示
630632
// delete target.msg;
@@ -636,11 +638,14 @@ var JSONResponse = {
636638
? JSONResponse.compareWithStandard(target, real, folder, exceptKeys, ignoreTrend)
637639
: JSONResponse.compareWithBefore(target, real, folder, exceptKeys);
638640
} finally {
639-
target[codeName] = tCode;
640-
real[codeName] = rCode;
641-
642-
target.throw = tThrw;
643-
real.throw = rThrw;
641+
if (isMachineLearning || noBizCode != true) {
642+
target[codeName] = tCode;
643+
}
644+
if (noBizCode != true) {
645+
real[codeName] = rCode;
646+
target.throw = tThrw;
647+
real.throw = rThrw;
648+
}
644649
}
645650

646651
if (exceptions.length > 0 && (target.repeat || 0) <= 0 && (result || {}).code < JSONResponse.COMPARE_VALUE_CHANGE) {
@@ -1257,7 +1262,7 @@ var JSONResponse = {
12571262
},
12581263

12591264

1260-
updateFullStandard: function (standard, currentResponse, isML) {
1265+
updateFullStandard: function (standard, currentResponse, isML, noBizCode) {
12611266
if (currentResponse == null) {
12621267
return standard;
12631268
}
@@ -1271,7 +1276,7 @@ var JSONResponse = {
12711276
var msg = currentResponse.msg;
12721277

12731278
var hasCode = standard.code != null;
1274-
var isCodeChange = standard.code != code;
1279+
var isCodeChange = noBizCode != true && standard.code != code;
12751280
var exceptions = standard.exceptions || [];
12761281

12771282
delete currentResponse.code; //code必须一致
@@ -1295,8 +1300,14 @@ var JSONResponse = {
12951300

12961301
var stddObj = isML ? (isCodeChange && hasCode ? standard : JSONResponse.updateStandard(standard, currentResponse)) : {};
12971302

1298-
currentResponse.code = code;
1299-
currentResponse.throw = thrw;
1303+
// if (noBizCode != true) {
1304+
currentResponse.code = code;
1305+
currentResponse.throw = thrw;
1306+
// }
1307+
1308+
if (hasCode || isML) {
1309+
stddObj.code = code || 0;
1310+
}
13001311

13011312
if (isCodeChange) {
13021313
if (hasCode != true) { // 走正常分支

APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/js/main.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,9 @@
227227
newVal[k] = vi[k]; //提升性能
228228
if (App.isFullAssert) {
229229
try {
230-
var tr = App.currentRemoteItem.TestRecord || {};
231-
var d = App.currentRemoteItem.Document || {};
230+
var cri = App.currentRemoteItem || {};
231+
var tr = cri.TestRecord || {};
232+
var d = cri.Document || {};
232233
var standard = App.isMLEnabled ? tr.standard : tr.response;
233234
var standardObj = StringUtil.isEmpty(standard, true) ? null : JSON.parse(standard);
234235
var tests = App.tests[String(App.currentAccountIndex)] || {};
@@ -285,8 +286,9 @@
285286
newVal[k] = val[k]; //提升性能
286287
if (App.isFullAssert) {
287288
try {
288-
var tr = App.currentRemoteItem.TestRecord || {};
289-
var d = App.currentRemoteItem.Document || {};
289+
var cri = App.currentRemoteItem || {};
290+
var tr = cri.TestRecord || {};
291+
var d = cri.Document || {};
290292
var standard = App.isMLEnabled ? tr.standard : tr.response;
291293
var standardObj = StringUtil.isEmpty(standard, true) ? null : JSON.parse(standard);
292294
var tests = App.tests[String(App.currentAccountIndex)] || {};
@@ -1553,8 +1555,9 @@ https://github.com/Tencent/APIJSON/issues
15531555
newVal[k] = vi[k]; //提升性能
15541556
if (this.isFullAssert) {
15551557
try {
1556-
var tr = this.currentRemoteItem.TestRecord || {};
1557-
var d = this.currentRemoteItem.Document || {};
1558+
var cri = this.currentRemoteItem || {};
1559+
var tr = cri.TestRecord || {};
1560+
var d = cri.Document || {};
15581561
var standard = this.isMLEnabled ? tr.standard : tr.response;
15591562
var standardObj = StringUtil.isEmpty(standard, true) ? null : JSON.parse(standard);
15601563
var tests = this.tests[String(this.currentAccountIndex)] || {};
@@ -1600,8 +1603,9 @@ https://github.com/Tencent/APIJSON/issues
16001603
for (var k in ret) {
16011604
if (this.isFullAssert) {
16021605
try {
1603-
var tr = this.currentRemoteItem.TestRecord || {};
1604-
var d = this.currentRemoteItem.Document || {};
1606+
var cri = this.currentRemoteItem || {};
1607+
var tr = cri.TestRecord || {};
1608+
var d = cri.Document || {};
16051609
var standard = this.isMLEnabled ? tr.standard : tr.response;
16061610
var standardObj = StringUtil.isEmpty(standard, true) ? null : JSON.parse(standard);
16071611
var tests = this.tests[String(this.currentAccountIndex)] || {};

0 commit comments

Comments
 (0)