提交 c4b39b79 编写于 作者: J jack870131

[IoTDB-174]Add interfaces for querying device or timeseries number

上级 18ae6c76
......@@ -63,6 +63,7 @@ Requires that you include the packages containing the JDBC classes needed for da
import java.sql.*;
import org.apache.iotdb.jdbc.IoTDBSQLException;
public class JDBCExample {
/**
* Before executing a SQL statement with a Statement object, you need to create a Statement object using the createStatement() method of the Connection object.
* After creating a Statement object, you can use its execute() method to execute a SQL statement
......@@ -98,6 +99,16 @@ import org.apache.iotdb.jdbc.IoTDBSQLException;
//Show time series
statement.execute("SHOW TIMESERIES root.demo");
outputResult(statement.getResultSet());
//Count time series
statement.execute("COUNT TIMESERIES root");
outputResult(statement.getResultSet());
//Count nodes at the given level
statement.execute("COUNT NODES root LEVEL=3");
outputResult(statement.getResultSet());
//Count timeseries group by each node at the given level
statement.execute("COUNT TIMESERIES root GROUP BY LEVEL=3");
outputResult(statement.getResultSet());
//Execute insert statements in batch
statement.addBatch("insert into root.demo(timestamp,s0) values(1,1);");
......@@ -187,4 +198,5 @@ import org.apache.iotdb.jdbc.IoTDBSQLException;
System.out.println("--------------------------\n");
}
}
}
```
\ No newline at end of file
......@@ -32,6 +32,12 @@ public class Constant {
public static final String GLOBAL_SHOW_TIMESERIES_REQ = "SHOW_TIMESERIES";
public static final String GLOBAL_COUNT_TIMESERIES_REQ = "COUNT_TIMESERIES";
public static final String GLOBAL_COUNT_NODE_TIMESERIES_REQ = "COUNT_NODE_TIMESERIES";
public static final String GLOBAL_COUNT_NODES_REQ = "COUNT_NODES";
public static final String GLOBAL_SHOW_STORAGE_GROUP_REQ = "SHOW_STORAGE_GROUP";
public static final String GLOBAL_COLUMNS_REQ = "ALL_COLUMNS";
......@@ -41,4 +47,7 @@ public class Constant {
public static final String CATALOG_TIMESERIES = "ts";
public static final String CATALOG_STORAGE_GROUP = "sg";
public static final String CATALOG_DEVICE = "delta";
public static final String COUNT_TIMESERIES = "cntts";
public static final String COUNT_NODE_TIMESERIES = "cnttsbg";
public static final String COUNT_NODES = "cntnode";
}
......@@ -18,11 +18,7 @@
*/
package org.apache.iotdb.jdbc;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.RowIdLifetime;
import java.sql.SQLException;
import java.sql.*;
import java.util.List;
import java.util.Set;
import org.apache.iotdb.rpc.IoTDBRPCException;
......@@ -89,7 +85,7 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
} catch (IoTDBRPCException e) {
throw new IoTDBSQLException(e.getMessage());
}
return new IoTDBMetadataResultSet(resp.getColumnsList(), null, null);
return new IoTDBMetadataResultSet(resp.getColumnsList(), IoTDBMetadataResultSet.MetadataType.COLUMN);
} catch (TException e) {
throw new TException("Conncetion error when fetching column metadata", e);
}
......@@ -103,7 +99,7 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
} catch (IoTDBRPCException e) {
throw new IoTDBSQLException(e.getMessage());
}
return new IoTDBMetadataResultSet(resp.getColumnsList(), null, null);
return new IoTDBMetadataResultSet(resp.getColumnsList(), IoTDBMetadataResultSet.MetadataType.COLUMN);
} catch (TException e) {
throw new TException("Conncetion error when fetching delta object metadata", e);
}
......@@ -117,7 +113,7 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
throw new IoTDBSQLException(e.getMessage());
}
Set<String> showStorageGroup = resp.getShowStorageGroups();
return new IoTDBMetadataResultSet(null, showStorageGroup, null);
return new IoTDBMetadataResultSet(showStorageGroup, IoTDBMetadataResultSet.MetadataType.STORAGE_GROUP);
} catch (TException e) {
throw new TException("Conncetion error when fetching storage group metadata", e);
}
......@@ -132,10 +128,87 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
throw new IoTDBSQLException(e.getMessage());
}
List<List<String>> showTimeseriesList = resp.getShowTimeseriesList();
return new IoTDBMetadataResultSet(null, null, showTimeseriesList);
return new IoTDBMetadataResultSet(showTimeseriesList, IoTDBMetadataResultSet.MetadataType.TIMESERIES);
} catch (TException e) {
throw new TException("Conncetion error when fetching timeseries metadata", e);
}
case Constant.COUNT_TIMESERIES:
req = new TSFetchMetadataReq(Constant.GLOBAL_COUNT_TIMESERIES_REQ);
req.setColumnPath(schemaPattern);
try {
TSFetchMetadataResp resp = client.fetchMetadata(req);
try {
RpcUtils.verifySuccess(resp.getStatus());
} catch (IoTDBRPCException e) {
throw new IoTDBSQLException(e.getMessage());
}
return new IoTDBMetadataResultSet(resp.getColumnsList().size(), IoTDBMetadataResultSet.MetadataType.COUNT_TIMESERIES);
} catch (TException e) {
throw new TException("Connection error when fetching timeseries metadata", e);
}
default:
throw new SQLException(catalog + " is not supported. Please refer to the user guide"
+ " for more details.");
}
}
public ResultSet getNodes(String catalog, String schemaPattern, String columnPattern,
String devicePattern, String nodeLevel) throws SQLException {
try {
return getNodesFunc(catalog, nodeLevel);
} catch (TException e) {
boolean flag = connection.reconnect();
this.client = connection.client;
if (flag) {
try {
return getNodesFunc(catalog, nodeLevel);
} catch (TException e2) {
throw new SQLException(String.format("Fail to get columns catalog=%s, schemaPattern=%s,"
+ " columnPattern=%s, devicePattern=%s, nodeLevel=%s after reconnecting."
+ " please check server status",
catalog, schemaPattern, columnPattern, devicePattern, nodeLevel));
}
} else {
throw new SQLException(String.format(
"Fail to reconnect to server when getting columns catalog=%s, schemaPattern=%s,"
+ " columnPattern=%s, devicePattern=%s, nodeLevel=%s after reconnecting. "
+ "please check server status",
catalog, schemaPattern, columnPattern, devicePattern, nodeLevel));
}
}
}
private ResultSet getNodesFunc(String catalog, String nodeLevel) throws TException, SQLException {
TSFetchMetadataReq req;
switch (catalog) {
case Constant.COUNT_NODES:
req = new TSFetchMetadataReq(Constant.GLOBAL_COUNT_NODES_REQ);
req.setNodeLevel(nodeLevel);
try {
TSFetchMetadataResp resp = client.fetchMetadata(req);
try {
RpcUtils.verifySuccess(resp.getStatus());
} catch (IoTDBRPCException e) {
throw new IoTDBSQLException(e.getMessage());
}
return new IoTDBMetadataResultSet(resp.getNodesList().size(), IoTDBMetadataResultSet.MetadataType.COUNT_NODES);
} catch (TException e) {
throw new TException("Conncetion error when fetching node metadata", e);
}
case Constant.COUNT_NODE_TIMESERIES:
req = new TSFetchMetadataReq(Constant.GLOBAL_COUNT_NODE_TIMESERIES_REQ);
req.setNodeLevel(nodeLevel);
try {
TSFetchMetadataResp resp = client.fetchMetadata(req);
try {
RpcUtils.verifySuccess(resp.getStatus());
} catch (IoTDBRPCException e) {
throw new IoTDBSQLException(e.getMessage());
}
return new IoTDBMetadataResultSet(resp.getNodeTimeseriesNum(), IoTDBMetadataResultSet.MetadataType.COUNT_NODE_TIMESERIES);
} catch (TException e) {
throw new TException("Conncetion error when fetching node metadata", e);
}
default:
throw new SQLException(catalog + " is not supported. Please refer to the user guide"
+ " for more details.");
......
......@@ -20,19 +20,17 @@ package org.apache.iotdb.jdbc;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.sql.Time;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.sql.*;
import java.util.*;
public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
public static final String GET_STRING_COLUMN = "COLUMN";
public static final String GET_STRING_STORAGE_GROUP = "STORAGE_GROUP";
public static final String GET_STRING_TIMESERIES_NUM = "TIMESERIES_NUM";
public static final String GET_STRING_NODES_NUM = "NODE_NUM";
public static final String GET_STRING_NODE_PATH = "NODE_PATH";
public static final String GET_STRING_NODE_TIMESERIES_NUM = "NODE_TIMESERIES_NUM";
public static final String GET_STRING_TIMESERIES_NAME = "Timeseries";
public static final String GET_STRING_TIMESERIES_STORAGE_GROUP = "Storage Group";
public static final String GET_STRING_TIMESERIES_DATATYPE = "DataType";
......@@ -42,6 +40,13 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
private String currentColumn;
private String currentStorageGroup;
private List<String> currentTimeseries;
private List<String> timeseriesNumList;
private List<String> nodesNumList;
private Map<String, String> nodeTimeseriesNumMap;
private String timeseriesNum;
private String nodesNum;
private String currentNode;
private String currentNodeTimeseriesNum;
// for display
private int colCount; // the number of columns for show
private String[] showLabels; // headers for show
......@@ -51,26 +56,52 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
/**
* Constructor used for the result of DatabaseMetadata.getColumns()
*/
public IoTDBMetadataResultSet(List<String> columns, Set<String> storageGroupSet,
List<List<String>> showTimeseriesList) throws SQLException {
if (columns != null) {
type = MetadataType.COLUMN;
colCount = 1;
showLabels = new String[]{"Column"};
columnItr = columns.iterator();
} else if (storageGroupSet != null) {
type = MetadataType.STORAGE_GROUP;
colCount = 1;
showLabels = new String[]{"Storage Group"};
columnItr = storageGroupSet.iterator();
} else if (showTimeseriesList != null) {
type = MetadataType.TIMESERIES;
colCount = 4;
showLabels = new String[]{GET_STRING_TIMESERIES_NAME, GET_STRING_TIMESERIES_STORAGE_GROUP,
public IoTDBMetadataResultSet(Object object, MetadataType type) throws SQLException {
this.type = type;
switch (type) {
case COLUMN:
List<String> columns = (List<String>) object;
colCount = 1;
showLabels = new String[]{"column"};
columnItr = columns.iterator();
break;
case STORAGE_GROUP:
Set<String> storageGroupSet = (Set<String>) object;
colCount = 1;
showLabels = new String[]{"Storage Group"};
columnItr = storageGroupSet.iterator();
break;
case TIMESERIES:
List<List<String>> showTimeseriesList = (List<List<String>>) object;
colCount = 4;
showLabels = new String[]{GET_STRING_TIMESERIES_NAME, GET_STRING_TIMESERIES_STORAGE_GROUP,
GET_STRING_TIMESERIES_DATATYPE, GET_STRING_TIMESERIES_ENCODING};
columnItr = showTimeseriesList.iterator();
} else {
throw new SQLException("TsfileMetadataResultSet constructor is wrongly used.");
columnItr = showTimeseriesList.iterator();
break;
case COUNT_TIMESERIES:
String tsNum = (String) object.toString();
timeseriesNumList = new ArrayList<>();
timeseriesNumList.add(tsNum);
colCount = 1;
showLabels = new String[]{"count"};
columnItr = timeseriesNumList.iterator();
break;
case COUNT_NODES:
String ndNum = (String) object.toString();
nodesNumList = new ArrayList<>();
nodesNumList.add(ndNum);
colCount = 1;
showLabels = new String[]{"count"};
columnItr = nodesNumList.iterator();
break;
case COUNT_NODE_TIMESERIES:
nodeTimeseriesNumMap = (Map<String, String>) object;
colCount = 2;
showLabels = new String[]{"column", "count"};
columnItr = nodeTimeseriesNumMap.entrySet().iterator();
break;
default:
throw new SQLException("TsfileMetadataResultSet constructor is wrongly used.");
}
}
......@@ -198,12 +229,29 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
public boolean next() throws SQLException {
boolean hasNext = columnItr.hasNext();
if (hasNext) {
if (type == MetadataType.STORAGE_GROUP) {
currentStorageGroup = (String) columnItr.next();
} else if (type == MetadataType.COLUMN) {
currentColumn = (String) columnItr.next();
} else {
currentTimeseries = (List<String>) columnItr.next();
switch (type) {
case STORAGE_GROUP:
currentStorageGroup = (String) columnItr.next();
break;
case TIMESERIES:
currentTimeseries = (List<String>) columnItr.next();
break;
case COLUMN:
currentColumn = (String) columnItr.next();
break;
case COUNT_TIMESERIES:
timeseriesNum = (String) columnItr.next();
break;
case COUNT_NODES:
nodesNum = (String) columnItr.next();
break;
case COUNT_NODE_TIMESERIES:
Map.Entry pair = (Map.Entry) columnItr.next();
currentNode = (String) pair.getKey();
currentNodeTimeseriesNum = (String) pair.getValue();
break;
default:
break;
}
}
return hasNext;
......@@ -252,6 +300,17 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
return getString(GET_STRING_COLUMN);
}
break;
case COUNT_TIMESERIES:
if (columnIndex == 1) {
return getString(GET_STRING_TIMESERIES_NUM);
}
break;
case COUNT_NODES:
if (columnIndex == 1) {
return getString(GET_STRING_NODES_NUM);
}
case COUNT_NODE_TIMESERIES:
return columnIndex == 1 ? getString(GET_STRING_NODE_PATH) : getString(GET_STRING_NODE_TIMESERIES_NUM);
default:
break;
}
......@@ -274,6 +333,14 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
return currentTimeseries.get(3);
case GET_STRING_COLUMN:
return currentColumn;
case GET_STRING_TIMESERIES_NUM:
return timeseriesNum;
case GET_STRING_NODES_NUM:
return nodesNum;
case GET_STRING_NODE_PATH:
return currentNode;
case GET_STRING_NODE_TIMESERIES_NUM:
return currentNodeTimeseriesNum;
default:
break;
}
......@@ -311,6 +378,6 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
}
public enum MetadataType {
STORAGE_GROUP, TIMESERIES, COLUMN
STORAGE_GROUP, TIMESERIES, COLUMN, COUNT_TIMESERIES, COUNT_NODES, COUNT_NODE_TIMESERIES
}
}
......@@ -41,6 +41,8 @@ public class IoTDBStatement implements Statement {
private static final String SHOW_TIMESERIES_COMMAND_LOWERCASE = "show timeseries";
private static final String SHOW_STORAGE_GROUP_COMMAND_LOWERCASE = "show storage group";
private static final String COUNT_TIMESERIES_COMMAND_LOWERCASE = "count timeseries";
private static final String COUNT_NODES_COMMAND_LOWERCASE = "count nodes";
private static final String METHOD_NOT_SUPPORTED_STRING = "Method not supported";
ZoneId zoneId;
......@@ -236,6 +238,35 @@ public class IoTDBStatement implements Statement {
DatabaseMetaData databaseMetaData = connection.getMetaData();
resultSet = databaseMetaData.getColumns(Constant.CATALOG_STORAGE_GROUP, null, null, null);
return true;
} else if (sqlToLowerCase.startsWith(COUNT_TIMESERIES_COMMAND_LOWERCASE)) {
String[] cmdSplited = sqlToLowerCase.split("\\s+", 4);
if (cmdSplited.length != 3 && !(cmdSplited.length == 4 && cmdSplited[3].startsWith("group by level"))) {
throw new SQLException(
"Error format of \'COUNT TIMESERIES <PATH>\' or \'COUNT TIMESERIES <PATH> GROUP BY LEVEL=<INTEGER>\'");
}
if (cmdSplited.length == 3) {
String path = cmdSplited[2];
DatabaseMetaData databaseMetaData = connection.getMetaData();
resultSet = databaseMetaData.getColumns(Constant.COUNT_TIMESERIES, path, null, null);
return true;
} else {
String path = cmdSplited[2];
String level = cmdSplited[3].replaceAll(" ", "").substring(13);
IoTDBDatabaseMetadata databaseMetadata = (IoTDBDatabaseMetadata) connection.getMetaData();
resultSet = databaseMetadata.getNodes(Constant.COUNT_NODE_TIMESERIES, path, null, null, level);
return true;
}
} else if (sqlToLowerCase.startsWith(COUNT_NODES_COMMAND_LOWERCASE)) {
String[] cmdSplited = sql.split("\\s+", 4);
if (cmdSplited.length != 4 && !(cmdSplited[3].startsWith("level"))) {
throw new SQLException("Error format of \'COUNT NODES LEVEL=<INTEGER>\'");
} else {
String path = cmdSplited[2];
String level = cmdSplited[3].replaceAll(" ", "").substring(6);
IoTDBDatabaseMetadata databaseMetaData = (IoTDBDatabaseMetadata) connection.getMetaData();
resultSet = databaseMetaData.getNodes(Constant.COUNT_NODES, path, null, null, level);
return true;
}
} else {
TSExecuteStatementReq execReq = new TSExecuteStatementReq(sessionHandle, sql);
TSExecuteStatementResp execResp = client.executeStatement(execReq);
......
......@@ -21,16 +21,11 @@ package org.apache.iotdb.jdbc;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import org.apache.iotdb.rpc.TSStatusType;
import org.apache.iotdb.service.rpc.thrift.*;
import org.junit.Assert;
......@@ -94,8 +89,124 @@ public class IoTDBDatabaseMetadataTest {
when(fetchMetadataResp.getColumnsList()).thenReturn(columnList);
String standard =
"Column,\n" + "root.vehicle.d0.s0,\n" + "root.vehicle.d0.s1,\n" + "root.vehicle.d0.s2,\n";
try (ResultSet resultSet = databaseMetaData.getColumns(Constant.CATALOG_COLUMN, "root", null, null)) {
"column,\n" + "root.vehicle.d0.s0,\n" + "root.vehicle.d0.s1,\n" + "root.vehicle.d0.s2,\n";
try {
ResultSet resultSet = databaseMetaData.getColumns(Constant.CATALOG_COLUMN, "root", null, null);
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int colCount = resultSetMetaData.getColumnCount();
StringBuilder resultStr = new StringBuilder();
for (int i = 1; i < colCount + 1; i++) {
resultStr.append(resultSetMetaData.getColumnName(i)).append(",");
}
resultStr.append("\n");
while (resultSet.next()) {
for (int i = 1; i <= colCount; i++) {
resultStr.append(resultSet.getString(i)).append(",");
}
resultStr.append("\n");
}
Assert.assertEquals(resultStr.toString(), standard);
} catch (SQLException e) {
System.out.println(e);
}
}
/**
* get the timeseries number under a given path
*/
@SuppressWarnings("resource")
@Test
public void CountTimeseries() throws Exception {
List<String> columnList = new ArrayList<>();
columnList.add("root.vehicle.d0.s0");
columnList.add("root.vehicle.d0.s1");
columnList.add("root.vehicle.d0.s2");
when(fetchMetadataResp.getColumnsList()).thenReturn(columnList);
String standard = "count,\n" + "3,\n";
try {
ResultSet resultSet = databaseMetaData.getColumns(Constant.COUNT_TIMESERIES, "root", null, null);
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int colCount = resultSetMetaData.getColumnCount();
StringBuilder resultStr = new StringBuilder();
for (int i = 1; i < colCount + 1; i++) {
resultStr.append(resultSetMetaData.getColumnName(i)).append(",");
}
resultStr.append("\n");
while (resultSet.next()) {
for (int i = 1; i <= colCount; i++) {
resultStr.append(resultSet.getString(i)).append(",");
}
resultStr.append("\n");
}
Assert.assertEquals(resultStr.toString(), standard);
} catch (SQLException e) {
System.out.println(e);
}
}
/**
* get node number under a given node level
*/
@SuppressWarnings("resource")
@Test
public void CountNodes() throws Exception {
List<String> nodes = new ArrayList<>();
nodes.add("root.vehicle1.d1");
nodes.add("root.vehicle1.d2");
nodes.add("root.vehicle2.d3");
nodes.add("root.vehicle2.d4");
when(fetchMetadataResp.getNodesList()).thenReturn(nodes);
String standard = "count,\n" + "4,\n";
try {
IoTDBDatabaseMetadata metadata = (IoTDBDatabaseMetadata) databaseMetaData;
String level = "3";
ResultSet resultSet = metadata.getNodes(Constant.COUNT_NODES, "root", null, null, level);
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int colCount = resultSetMetaData.getColumnCount();
StringBuilder resultStr = new StringBuilder();
for (int i = 1; i < colCount + 1; i++) {
resultStr.append(resultSetMetaData.getColumnName(i)).append(",");
}
resultStr.append("\n");
while (resultSet.next()) {
for (int i = 1; i <= colCount; i++) {
resultStr.append(resultSet.getString(i)).append(",");
}
resultStr.append("\n");
}
Assert.assertEquals(resultStr.toString(), standard);
} catch (SQLException e) {
System.out.println(e);
}
}
/**
* get the timeseries number under a given node level
*/
@SuppressWarnings("resource")
@Test
public void CountNodeTimeseries() throws Exception {
Map<String, String> nodeTimeseriesNum = new LinkedHashMap<>();
nodeTimeseriesNum.put("root.vehicle.d1", "3");
nodeTimeseriesNum.put("root.vehicle.d2", "2");
nodeTimeseriesNum.put("root.vehicle.d3", "4");
nodeTimeseriesNum.put("root.vehicle.d4", "2");
when(fetchMetadataResp.getNodeTimeseriesNum()).thenReturn(nodeTimeseriesNum);
String standard = "column,count,\n"
+ "root.vehicle.d1,3,\n"
+ "root.vehicle.d2,2,\n"
+ "root.vehicle.d3,4,\n"
+ "root.vehicle.d4,2,\n";
try {
IoTDBDatabaseMetadata metadata = (IoTDBDatabaseMetadata) databaseMetaData;
String level = "3";
ResultSet resultSet = metadata.getNodes(Constant.COUNT_NODE_TIMESERIES, "root", null, null, level);
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int colCount = resultSetMetaData.getColumnCount();
StringBuilder resultStr = new StringBuilder();
......@@ -126,9 +237,10 @@ public class IoTDBDatabaseMetadataTest {
when(fetchMetadataResp.getColumnsList()).thenReturn(columnList);
String standard = "Column,\n" + "root.vehicle.d0,\n";
try (ResultSet resultSet = databaseMetaData
.getColumns(Constant.CATALOG_DEVICE, "vehicle", null, null)) {
String standard = "column,\n" + "root.vehicle.d0,\n";
try {
ResultSet resultSet = databaseMetaData
.getColumns(Constant.CATALOG_DEVICE, "vehicle", null, null);
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int colCount = resultSetMetaData.getColumnCount();
StringBuilder resultStr = new StringBuilder();
......
......@@ -247,6 +247,10 @@ public class MGraph implements Serializable {
return mtree.getAllStorageGroup();
}
List<String> getNodesList(String nodeLevel) {
return mtree.getNodesList(nodeLevel);
}
List<String> getLeafNodePathInNextLevel(String path) throws PathErrorException {
return mtree.getLeafNodePathInNextLevel(path);
}
......
......@@ -18,23 +18,12 @@
*/
package org.apache.iotdb.db.metadata;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.io.*;
import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
import org.apache.iotdb.db.conf.adapter.IoTDBConfigDynamicAdapter;
import org.apache.iotdb.db.engine.StorageEngine;
import org.apache.iotdb.db.exception.ConfigAdjusterException;
import org.apache.iotdb.db.exception.MetadataErrorException;
import org.apache.iotdb.db.exception.PathErrorException;
......@@ -770,6 +759,21 @@ public class MManager {
}
}
/**
* Get all nodes from the given level
*
* @return A List instance which stores all node at given level
*/
public List<String> getNodesList(String nodeLevel) {
lock.readLock().lock();
try {
return mgraph.getNodesList(nodeLevel);
} finally {
lock.readLock().unlock();
}
}
/**
* @param path A seriesPath represented one Delta object
* @return a list contains all column schema
......
......@@ -105,6 +105,16 @@ public class MNode implements Serializable {
this.isLeaf = isLeaf;
}
/**
* function for checking whether the mnode has child mnode.
*/
public boolean hasChildren() {
if (!isLeaf) {
return true;
}
return false;
}
/**
* function for checking whether mnode's children contain the given key.
*/
......
......@@ -18,17 +18,12 @@
*/
package org.apache.iotdb.db.metadata;
import java.io.Serializable;
import java.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.iotdb.db.exception.PathErrorException;
import org.apache.iotdb.tsfile.common.conf.TSFileConfig;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
......@@ -764,6 +759,36 @@ public class MTree implements Serializable {
}
}
/**
* Get all nodes at the given level in current Metadata Tree.
*
* @return a list contains all nodes at the given level
*/
List<String> getNodesList(String nodeLevel) {
List<String> res = new ArrayList<>();
int level = Integer.parseInt(nodeLevel);
MNode rootNode;
if ((rootNode = getRoot()) != null) {
findNodes(rootNode, "root", res, level);
}
return res;
}
private void findNodes(MNode node, String path, List<String> res, int targetLevel) {
if (node == null) {
return;
}
if (targetLevel == 1) {
res.add(path);
return;
}
if (node.hasChildren()) {
for (MNode child : node.getChildren().values()) {
findNodes(child, path + "." + child.toString(), res, targetLevel - 1);
}
}
}
/**
* Get all delta objects for given type.
*
......
......@@ -18,6 +18,17 @@
*/
package org.apache.iotdb.db.service;
import static org.apache.iotdb.db.conf.IoTDBConstant.*;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;
import org.apache.iotdb.db.auth.AuthException;
import org.apache.iotdb.db.auth.AuthorityChecker;
import org.apache.iotdb.db.auth.authorizer.IAuthorizer;
......@@ -281,10 +292,19 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
resp.setDataType(getSeriesType(req.getColumnPath()).toString());
status = new TS_Status(getStatus(TSStatusType.SUCCESS_STATUS));
break;
case "COUNT_TIMESERIES":
case "ALL_COLUMNS":
resp.setColumnsList(getPaths(req.getColumnPath()));
status = new TS_Status(getStatus(TSStatusType.SUCCESS_STATUS));
break;
case "COUNT_NODES":
resp.setNodesList(getNodesList(req.getNodeLevel()));
status = new TS_Status(getStatus(TSStatusType.SUCCESS_STATUS));
break;
case "COUNT_NODE_TIMESERIES":
resp.setNodeTimeseriesNum(getNodeTimeseriesNum(getNodesList(req.getNodeLevel())));
status = new TS_Status(getStatus(TSStatusType.SUCCESS_STATUS));
break;
default:
status = getStatus(TSStatusType.FETCH_METADATA_ERROR, req.getType());
break;
......@@ -302,6 +322,18 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
return resp;
}
private Map<String, String> getNodeTimeseriesNum(List<String> nodes) throws MetadataErrorException {
Map<String, String> nodeColumnsNum = new HashMap<>();
for (String columnPath : nodes) {
nodeColumnsNum.put(columnPath, Integer.toString(getPaths(columnPath).size()));
}
return nodeColumnsNum;
}
private List<String> getNodesList(String level) throws PathErrorException {
return MManager.getInstance().getNodesList(level);
}
private Set<String> getAllStorageGroups() throws PathErrorException {
return MManager.getInstance().getAllStorageGroup();
}
......
......@@ -214,7 +214,7 @@ public class IoTDBMetadataFetchIT {
*/
private void allColumns() throws SQLException {
String standard =
"Column,\n" + "root.ln.wf01.wt01.status,\n" + "root.ln.wf01.wt01.temperature,\n";
"column,\n" + "root.ln.wf01.wt01.status,\n" + "root.ln.wf01.wt01.temperature,\n";
try (ResultSet resultSet = databaseMetaData.getColumns(Constant.CATALOG_COLUMN, "root", null, null);) {
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
......@@ -238,7 +238,7 @@ public class IoTDBMetadataFetchIT {
* get all delta objects under a given column
*/
private void device() throws SQLException {
String standard = "Column,\n" + "root.ln.wf01.wt01,\n";
String standard = "column,\n" + "root.ln.wf01.wt01,\n";
try (ResultSet resultSet = databaseMetaData.getColumns(Constant.CATALOG_DEVICE, "ln", null,
......
......@@ -196,11 +196,14 @@ struct TSFetchMetadataResp{
4: optional string dataType
5: optional list<list<string>> showTimeseriesList
7: optional set<string> showStorageGroups
8: optional list<string> nodesList
9: optional map<string, string> nodeTimeseriesNum
}
struct TSFetchMetadataReq{
1: required string type
2: optional string columnPath
3: optional string nodeLevel
}
struct TSColumnSchema{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册