From 5b1a318cbd0be00b060e85e3d9dd3379e67199a6 Mon Sep 17 00:00:00 2001 From: qiaojialin <646274302@qq.com> Date: Sat, 24 Aug 2019 11:25:42 +0800 Subject: [PATCH] add session module and rename cli to client --- README.md | 4 +- client/pom.xml | 2 +- .../sbin/{start-cli.bat => start-client.bat} | 2 +- .../sbin/{start-cli.sh => start-client.sh} | 2 +- .../main/java/org/apache/iotdb/cli/Cli.java | 187 ----------- .../AbstractClient.java} | 10 +- .../java/org/apache/iotdb/client/Client.java | 308 +++++++++--------- .../WinCli.java => client/WinClient.java} | 6 +- .../java/org/apache/iotdb/tool/ExportCsv.java | 4 +- .../org/apache/iotdb/cli/AbstractCliIT.java | 223 ------------- .../apache/iotdb/client/AbstractClientIT.java | 223 +++++++++++++ .../iotdb/{cli => client}/AbstractScript.java | 2 +- .../StartClientScriptIT.java} | 10 +- .../apache/iotdb/tool/ExportCsvTestIT.java | 2 +- .../apache/iotdb/tool/ImportCsvTestIT.java | 2 +- docs/Development.md | 4 +- .../UserGuide/1-Overview/3-Scenario.md | 4 +- .../1-Session API.md} | 44 ++- .../UserGuide/9-Tools-Cli.md | 6 +- .../Frequently asked questions.md | 6 +- .../UserGuide/1-Overview/3-Scenario.md | 4 +- .../3-Operation Manual/3-Data Import.md | 2 +- .../1-IoTDB Query Statement.md | 6 +- .../UserGuide/6-JDBC API/1-JDBC API.md | 4 +- .../1-Session API.md} | 36 +- example/pom.xml | 2 +- example/{client => session}/pom.xml | 2 +- .../java/org/apache/iotdb}/JDBCExample.java | 11 +- .../org/apache/iotdb/SessionExample.java} | 15 +- pom.xml | 1 + .../org/apache/iotdb/db/sql/parse/TSParser.g | 2 +- .../org/apache/iotdb/db/utils/MemUtils.java | 4 +- service-rpc/src/main/thrift/rpc.thrift | 2 +- session/pom.xml | 62 ++++ .../exception/IoTDBSessionException.java | 0 .../org/apache/iotdb/session/Session.java | 189 +++++++++++ 36 files changed, 736 insertions(+), 657 deletions(-) rename client/src/assembly/resources/sbin/{start-cli.bat => start-client.bat} (96%) rename client/src/assembly/resources/sbin/{start-cli.sh => start-client.sh} (97%) delete mode 100644 client/src/main/java/org/apache/iotdb/cli/Cli.java rename client/src/main/java/org/apache/iotdb/{cli/AbstractCli.java => client/AbstractClient.java} (99%) rename client/src/main/java/org/apache/iotdb/{cli/WinCli.java => client/WinClient.java} (97%) delete mode 100644 client/src/test/java/org/apache/iotdb/cli/AbstractCliIT.java create mode 100644 client/src/test/java/org/apache/iotdb/client/AbstractClientIT.java rename client/src/test/java/org/apache/iotdb/{cli => client}/AbstractScript.java (98%) rename client/src/test/java/org/apache/iotdb/{cli/StartCliScriptIT.java => client/StartClientScriptIT.java} (94%) rename docs/Documentation-CHN/UserGuide/{7-Client API/1-Client API.md => 7-Session API/1-Session API.md} (65%) rename docs/Documentation/UserGuide/{7-Client API/1-Client API.md => 7-Session API/1-Session API.md} (69%) rename example/{client => session}/pom.xml (97%) rename example/{client/src/main/java/org/apache/iotdb/client => session/src/main/java/org/apache/iotdb}/JDBCExample.java (88%) rename example/{client/src/main/java/org/apache/iotdb/client/ClientExample.java => session/src/main/java/org/apache/iotdb/SessionExample.java} (88%) create mode 100644 session/pom.xml rename {client => session}/src/main/java/org/apache/iotdb/exception/IoTDBSessionException.java (100%) create mode 100644 session/src/main/java/org/apache/iotdb/session/Session.java diff --git a/README.md b/README.md index 553ac6cb300..f62258238f2 100644 --- a/README.md +++ b/README.md @@ -183,9 +183,9 @@ The server can be stopped with ctrl-C or the following script: > $IOTDB_HOME\sbin\stop-server.bat ``` -### Start Cli +### Start Client -Now let's trying to read and write some data from IoTDB using our Cli. To start the client, you need to explicit the server's IP and PORT as well as the USER_NAME and PASSWORD. +Now let's trying to read and write some data from IoTDB using our Client. To start the client, you need to explicit the server's IP and PORT as well as the USER_NAME and PASSWORD. ``` # You can first build cli project diff --git a/client/pom.xml b/client/pom.xml index 5185788c6a0..ef1ea30ae9a 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -28,7 +28,7 @@ ../pom.xml iotdb-client - IoTDB Client and Cli + IoTDB Client false ${cli.test.skip} diff --git a/client/src/assembly/resources/sbin/start-cli.bat b/client/src/assembly/resources/sbin/start-client.bat similarity index 96% rename from client/src/assembly/resources/sbin/start-cli.bat rename to client/src/assembly/resources/sbin/start-client.bat index 61a6b0c9bae..727bfdb288a 100755 --- a/client/src/assembly/resources/sbin/start-cli.bat +++ b/client/src/assembly/resources/sbin/start-client.bat @@ -28,7 +28,7 @@ pushd %~dp0.. if NOT DEFINED IOTDB_CLI_HOME set IOTDB_CLI_HOME=%CD% popd -if NOT DEFINED MAIN_CLASS set MAIN_CLASS=org.apache.iotdb.cli.Cli +if NOT DEFINED MAIN_CLASS set MAIN_CLASS=org.apache.iotdb.client.Client if NOT DEFINED JAVA_HOME goto :err @REM ----------------------------------------------------------------------------- diff --git a/client/src/assembly/resources/sbin/start-cli.sh b/client/src/assembly/resources/sbin/start-client.sh similarity index 97% rename from client/src/assembly/resources/sbin/start-cli.sh rename to client/src/assembly/resources/sbin/start-client.sh index 1a147bb0672..4591159ddf7 100755 --- a/client/src/assembly/resources/sbin/start-cli.sh +++ b/client/src/assembly/resources/sbin/start-client.sh @@ -24,7 +24,7 @@ if [ -z "${IOTDB_CLI_HOME}" ]; then fi -MAIN_CLASS=org.apache.iotdb.cli.Cli +MAIN_CLASS=org.apache.iotdb.client.Client CLASSPATH="" diff --git a/client/src/main/java/org/apache/iotdb/cli/Cli.java b/client/src/main/java/org/apache/iotdb/cli/Cli.java deleted file mode 100644 index 27651d6f166..00000000000 --- a/client/src/main/java/org/apache/iotdb/cli/Cli.java +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.iotdb.cli; - -import java.io.IOException; -import java.sql.DriverManager; -import java.sql.SQLException; -import jline.console.ConsoleReader; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.iotdb.exception.ArgsErrorException; -import org.apache.iotdb.jdbc.Config; -import org.apache.iotdb.jdbc.IoTDBConnection; -import org.apache.thrift.TException; - -public class Cli extends AbstractCli { - - private static CommandLine commandLine; - - /** - * IoTDB CLI main function. - * - * @param args launch arguments - * @throws ClassNotFoundException ClassNotFoundException - */ - public static void main(String[] args) throws ClassNotFoundException { - Class.forName(Config.JDBC_DRIVER_NAME); - Options options = createOptions(); - HelpFormatter hf = new HelpFormatter(); - hf.setWidth(MAX_HELP_CONSOLE_WIDTH); - commandLine = null; - - String[] newArgs; - String[] newArgs2; - - if (args == null || args.length == 0) { - println( - "Require more params input, eg. ./start-cli.sh(start-cli.bat if Windows) " - + "-h xxx.xxx.xxx.xxx -p xxxx -u xxx."); - println("For more information, please check the following hint."); - hf.printHelp(SCRIPT_HINT, options, true); - return; - } - init(); - newArgs = removePasswordArgs(args); - newArgs2 = processExecuteArgs(newArgs); - boolean continues = parseCommandLine(options, newArgs2, hf); - if (!continues) { - return; - } - - serve(); - } - - private static boolean parseCommandLine(Options options, String[] newArgs, HelpFormatter hf) { - try { - CommandLineParser parser = new DefaultParser(); - commandLine = parser.parse(options, newArgs); - if (commandLine.hasOption(HELP_ARGS)) { - hf.printHelp(SCRIPT_HINT, options, true); - return false; - } - if (commandLine.hasOption(ISO8601_ARGS)) { - setTimeFormat("long"); - } - if (commandLine.hasOption(MAX_PRINT_ROW_COUNT_ARGS)) { - setMaxDisplayNumber(commandLine.getOptionValue(MAX_PRINT_ROW_COUNT_ARGS)); - } - } catch (ParseException e) { - println( - "Require more params input, eg. ./start-cli.sh(start-cli.bat if Windows) " - + "-h xxx.xxx.xxx.xxx -p xxxx -u xxx."); - println("For more information, please check the following hint."); - hf.printHelp(IOTDB_CLI_PREFIX, options, true); - handleException(e); - return false; - } catch (NumberFormatException e) { - println( - IOTDB_CLI_PREFIX + "> error format of max print row count, it should be number"); - handleException(e); - return false; - } - return true; - } - - private static void serve() { - try (ConsoleReader reader = new ConsoleReader()) { - reader.setExpandEvents(false); - - host = checkRequiredArg(HOST_ARGS, HOST_NAME, commandLine, false, host); - port = checkRequiredArg(PORT_ARGS, PORT_NAME, commandLine, false, port); - username = checkRequiredArg(USERNAME_ARGS, USERNAME_NAME, commandLine, true, null); - - password = commandLine.getOptionValue(PASSWORD_ARGS); - if (password == null) { - password = reader.readLine("please input your password:", '\0'); - } - if (hasExecuteSQL) { - try (IoTDBConnection connection = (IoTDBConnection) DriverManager - .getConnection(Config.IOTDB_URL_PREFIX + host + ":" + port + "/", username, password)) { - properties = connection.getServerProperties(); - AGGREGRATE_TIME_LIST.addAll(properties.getSupportedTimeAggregationOperations()); - processCmd(execute, connection); - return; - } catch (SQLException e) { - handleException(e); - } - } - - receiveCommands(reader); - } catch (ArgsErrorException e) { - println(IOTDB_CLI_PREFIX + "> input params error because" + e.getMessage()); - handleException(e); - } catch (Exception e) { - println(IOTDB_CLI_PREFIX + "> exit client with error " + e.getMessage()); - handleException(e); - } - } - - private static void receiveCommands(ConsoleReader reader) throws TException, IOException { - try (IoTDBConnection connection = (IoTDBConnection) DriverManager - .getConnection(Config.IOTDB_URL_PREFIX + host + ":" + port + "/", username, password)) { - String s; - properties = connection.getServerProperties(); - AGGREGRATE_TIME_LIST.addAll(properties.getSupportedTimeAggregationOperations()); - TIMESTAMP_PRECISION = properties.getTimestampPrecision(); - - echoStarting(); - displayLogo(properties.getVersion()); - println(IOTDB_CLI_PREFIX + "> login successfully"); - while (true) { - s = reader.readLine(IOTDB_CLI_PREFIX + "> ", null); - boolean continues = processCmd(s, connection); - if (!continues) { - break; - } - } - } catch (SQLException e) { - println(String - .format("%s> %s Host is %s, port is %s.", IOTDB_CLI_PREFIX, e.getMessage(), host, - port)); - handleException(e); - } - } - - private static boolean processCmd(String s, IoTDBConnection connection) { - if (s == null) { - return true; - } - String[] cmds = s.trim().split(";"); - for (int i = 0; i < cmds.length; i++) { - String cmd = cmds[i]; - if (cmd != null && !"".equals(cmd.trim())) { - OperationResult result = handleInputCmd(cmd, connection); - switch (result) { - case STOP_OPER: - return false; - case CONTINUE_OPER: - continue; - default: - break; - } - } - } - return true; - } -} diff --git a/client/src/main/java/org/apache/iotdb/cli/AbstractCli.java b/client/src/main/java/org/apache/iotdb/client/AbstractClient.java similarity index 99% rename from client/src/main/java/org/apache/iotdb/cli/AbstractCli.java rename to client/src/main/java/org/apache/iotdb/client/AbstractClient.java index 434a60b5ff3..3dedc0c3e13 100644 --- a/client/src/main/java/org/apache/iotdb/cli/AbstractCli.java +++ b/client/src/main/java/org/apache/iotdb/client/AbstractClient.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.cli; +package org.apache.iotdb.client; import java.io.PrintStream; import java.sql.ResultSet; @@ -47,7 +47,7 @@ import org.apache.iotdb.jdbc.IoTDBQueryResultSet; import org.apache.iotdb.service.rpc.thrift.ServerProperties; import org.apache.thrift.TException; -public abstract class AbstractCli { +public abstract class AbstractClient { static final String HOST_ARGS = "h"; static final String HOST_NAME = "host"; @@ -79,7 +79,7 @@ public abstract class AbstractCli { static final String SHOW_FETCH_SIZE = "show fetch_size"; private static final String HELP = "help"; static final String IOTDB_CLI_PREFIX = "IoTDB"; - static final String SCRIPT_HINT = "./start-cli.sh(start-cli.bat if Windows)"; + static final String SCRIPT_HINT = "./start-client.sh(start-client.bat if Windows)"; static final String QUIT_COMMAND = "quit"; static final String EXIT_COMMAND = "exit"; static final String SHOW_METADATA_COMMAND = "show timeseries"; @@ -176,7 +176,7 @@ public abstract class AbstractCli { } /** - * CLI result output. + * Client result output. * * @param res result set * @param printToConsole print to console @@ -585,7 +585,7 @@ public abstract class AbstractCli { static void echoStarting(){ println("---------------------"); - println("Starting IoTDB Cli"); + println("Starting IoTDB Client"); println("---------------------"); } diff --git a/client/src/main/java/org/apache/iotdb/client/Client.java b/client/src/main/java/org/apache/iotdb/client/Client.java index 79b3bbbc8df..9068e77d79e 100644 --- a/client/src/main/java/org/apache/iotdb/client/Client.java +++ b/client/src/main/java/org/apache/iotdb/client/Client.java @@ -7,7 +7,7 @@ * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an @@ -18,172 +18,170 @@ */ package org.apache.iotdb.client; -import java.time.ZoneId; -import org.apache.iotdb.exception.IoTDBSessionException; +import java.io.IOException; +import java.sql.DriverManager; +import java.sql.SQLException; +import jline.console.ConsoleReader; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.iotdb.exception.ArgsErrorException; import org.apache.iotdb.jdbc.Config; import org.apache.iotdb.jdbc.IoTDBConnection; -import org.apache.iotdb.jdbc.IoTDBSQLException; -import org.apache.iotdb.jdbc.Utils; -import org.apache.iotdb.service.rpc.thrift.TSBatchInsertionReq; -import org.apache.iotdb.service.rpc.thrift.TSCloseSessionReq; -import org.apache.iotdb.service.rpc.thrift.TSExecuteBatchStatementResp; -import org.apache.iotdb.service.rpc.thrift.TSGetTimeZoneResp; -import org.apache.iotdb.service.rpc.thrift.TSIService; -import org.apache.iotdb.service.rpc.thrift.TSOpenSessionReq; -import org.apache.iotdb.service.rpc.thrift.TSOpenSessionResp; -import org.apache.iotdb.service.rpc.thrift.TSProtocolVersion; -import org.apache.iotdb.service.rpc.thrift.TSSetTimeZoneReq; -import org.apache.iotdb.service.rpc.thrift.TSSetTimeZoneResp; -import org.apache.iotdb.service.rpc.thrift.TS_SessionHandle; -import org.apache.iotdb.tsfile.write.record.RowBatch; -import org.apache.iotdb.tsfile.write.schema.MeasurementSchema; import org.apache.thrift.TException; -import org.apache.thrift.protocol.TBinaryProtocol; -import org.apache.thrift.protocol.TCompactProtocol; -import org.apache.thrift.transport.TSocket; -import org.apache.thrift.transport.TTransportException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -public class Client { +public class Client extends AbstractClient { - private static final Logger logger = LoggerFactory.getLogger(Client.class); - private String host; - private int port; - private String username; - private String password; - private final TSProtocolVersion protocolVersion = TSProtocolVersion.IOTDB_SERVICE_PROTOCOL_V1; - public TSIService.Iface client = null; - private TS_SessionHandle sessionHandle = null; - private TSocket transport; - private boolean isClosed = true; - private ZoneId zoneId; + private static CommandLine commandLine; - public Client(String host, int port) { - this(host, port, Config.DEFAULT_USER, Config.DEFALUT_PASSWORD); - } + /** + * IoTDB Client main function. + * + * @param args launch arguments + * @throws ClassNotFoundException ClassNotFoundException + */ + public static void main(String[] args) throws ClassNotFoundException { + Class.forName(Config.JDBC_DRIVER_NAME); + Options options = createOptions(); + HelpFormatter hf = new HelpFormatter(); + hf.setWidth(MAX_HELP_CONSOLE_WIDTH); + commandLine = null; - public Client(String host, String port, String username, String password) { - this(host, Integer.parseInt(port), username, password); - } + String[] newArgs; + String[] newArgs2; - public Client(String host, int port, String username, String password) { - this.host = host; - this.port = port; - this.username = username; - this.password = password; - } - - public void open() { - open(false, 0); - } - - public void open(boolean enableRPCCompression, int connectionTimeoutInMs) { - transport = new TSocket(host, port, connectionTimeoutInMs); - if (!transport.isOpen()) { - try { - transport.open(); - } catch (TTransportException e) { - throw new IoTDBSessionException(e); - } - } - - if(enableRPCCompression) { - client = new TSIService.Client(new TCompactProtocol(transport)); - } - else { - client = new TSIService.Client(new TBinaryProtocol(transport)); - } - - TSOpenSessionReq openReq = new TSOpenSessionReq(TSProtocolVersion.IOTDB_SERVICE_PROTOCOL_V1); - openReq.setUsername(username); - openReq.setPassword(password); - - try { - TSOpenSessionResp openResp = client.openSession(openReq); - - // validate connection - try { - Utils.verifySuccess(openResp.getStatus()); - } catch (IoTDBSQLException e) { - transport.close(); - throw e; - } - - if (protocolVersion.getValue() != openResp.getServerProtocolVersion().getValue()) { - throw new TException(String - .format("Protocol not supported, Client version is {}, but Server version is {}", - protocolVersion.getValue(), openResp.getServerProtocolVersion().getValue())); - } - - sessionHandle = openResp.getSessionHandle(); - - if (zoneId != null) { - setTimeZone(zoneId.toString()); - } else { - zoneId = ZoneId.of(getTimeZone()); - } - - } catch (TException | IoTDBSQLException e) { - throw new IoTDBSessionException(String.format("Can not open session to %s:%s with user: %s.", - host, port, username), e); - } - isClosed = false; - - client = IoTDBConnection.newSynchronizedClient(client); - - } - - public void close() { - if (isClosed) { + if (args == null || args.length == 0) { + println( + "Require more params input, eg. ./start-client.sh(start-client.bat if Windows) " + + "-h xxx.xxx.xxx.xxx -p xxxx -u xxx."); + println("For more information, please check the following hint."); + hf.printHelp(SCRIPT_HINT, options, true); return; } - TSCloseSessionReq req = new TSCloseSessionReq(sessionHandle); + init(); + newArgs = removePasswordArgs(args); + newArgs2 = processExecuteArgs(newArgs); + boolean continues = parseCommandLine(options, newArgs2, hf); + if (!continues) { + return; + } + + serve(); + } + + private static boolean parseCommandLine(Options options, String[] newArgs, HelpFormatter hf) { try { - client.closeSession(req); - } catch (TException e) { - throw new IoTDBSessionException("Error occurs when closing session at server. Maybe server is down.", e); - } finally { - isClosed = true; - if (transport != null) { - transport.close(); + CommandLineParser parser = new DefaultParser(); + commandLine = parser.parse(options, newArgs); + if (commandLine.hasOption(HELP_ARGS)) { + hf.printHelp(SCRIPT_HINT, options, true); + return false; + } + if (commandLine.hasOption(ISO8601_ARGS)) { + setTimeFormat("long"); + } + if (commandLine.hasOption(MAX_PRINT_ROW_COUNT_ARGS)) { + setMaxDisplayNumber(commandLine.getOptionValue(MAX_PRINT_ROW_COUNT_ARGS)); + } + } catch (ParseException e) { + println( + "Require more params input, eg. ./start-client.sh(start-client.bat if Windows) " + + "-h xxx.xxx.xxx.xxx -p xxxx -u xxx."); + println("For more information, please check the following hint."); + hf.printHelp(IOTDB_CLI_PREFIX, options, true); + handleException(e); + return false; + } catch (NumberFormatException e) { + println( + IOTDB_CLI_PREFIX + "> error format of max print row count, it should be number"); + handleException(e); + return false; + } + return true; + } + + private static void serve() { + try (ConsoleReader reader = new ConsoleReader()) { + reader.setExpandEvents(false); + + host = checkRequiredArg(HOST_ARGS, HOST_NAME, commandLine, false, host); + port = checkRequiredArg(PORT_ARGS, PORT_NAME, commandLine, false, port); + username = checkRequiredArg(USERNAME_ARGS, USERNAME_NAME, commandLine, true, null); + + password = commandLine.getOptionValue(PASSWORD_ARGS); + if (password == null) { + password = reader.readLine("please input your password:", '\0'); + } + if (hasExecuteSQL) { + try (IoTDBConnection connection = (IoTDBConnection) DriverManager + .getConnection(Config.IOTDB_URL_PREFIX + host + ":" + port + "/", username, password)) { + properties = connection.getServerProperties(); + AGGREGRATE_TIME_LIST.addAll(properties.getSupportedTimeAggregationOperations()); + processCmd(execute, connection); + return; + } catch (SQLException e) { + handleException(e); + } + } + + receiveCommands(reader); + } catch (ArgsErrorException e) { + println(IOTDB_CLI_PREFIX + "> input params error because" + e.getMessage()); + handleException(e); + } catch (Exception e) { + println(IOTDB_CLI_PREFIX + "> exit client with error " + e.getMessage()); + handleException(e); + } + } + + private static void receiveCommands(ConsoleReader reader) throws TException, IOException { + try (IoTDBConnection connection = (IoTDBConnection) DriverManager + .getConnection(Config.IOTDB_URL_PREFIX + host + ":" + port + "/", username, password)) { + String s; + properties = connection.getServerProperties(); + AGGREGRATE_TIME_LIST.addAll(properties.getSupportedTimeAggregationOperations()); + TIMESTAMP_PRECISION = properties.getTimestampPrecision(); + + echoStarting(); + displayLogo(properties.getVersion()); + println(IOTDB_CLI_PREFIX + "> login successfully"); + while (true) { + s = reader.readLine(IOTDB_CLI_PREFIX + "> ", null); + boolean continues = processCmd(s, connection); + if (!continues) { + break; + } + } + } catch (SQLException e) { + println(String + .format("%s> %s Host is %s, port is %s.", IOTDB_CLI_PREFIX, e.getMessage(), host, + port)); + handleException(e); + } + } + + private static boolean processCmd(String s, IoTDBConnection connection) { + if (s == null) { + return true; + } + String[] cmds = s.trim().split(";"); + for (int i = 0; i < cmds.length; i++) { + String cmd = cmds[i]; + if (cmd != null && !"".equals(cmd.trim())) { + OperationResult result = handleInputCmd(cmd, connection); + switch (result) { + case STOP_OPER: + return false; + case CONTINUE_OPER: + continue; + default: + break; + } } } + return true; } - - public TSExecuteBatchStatementResp insertBatch(RowBatch rowBatch) { - TSBatchInsertionReq request = new TSBatchInsertionReq(); - request.deviceId = rowBatch.deviceId; - for (MeasurementSchema measurementSchema: rowBatch.measurements) { - request.addToMeasurements(measurementSchema.getMeasurementId()); - request.addToTypes(measurementSchema.getType().ordinal()); - } - request.setTimestamps(Utils.getTimeBuffer(rowBatch)); - request.setValues(Utils.getValueBuffer(rowBatch)); - request.setSize(rowBatch.batchSize); - - try { - return client.insertBatch(request); - } catch (TException e) { - throw new IoTDBSessionException(e); - } - } - - public String getTimeZone() throws TException, IoTDBSQLException { - if (zoneId != null) { - return zoneId.toString(); - } - - TSGetTimeZoneResp resp = client.getTimeZone(); - Utils.verifySuccess(resp.getStatus()); - return resp.getTimeZone(); - } - - public void setTimeZone(String zoneId) throws TException, IoTDBSQLException { - TSSetTimeZoneReq req = new TSSetTimeZoneReq(zoneId); - TSSetTimeZoneResp resp = client.setTimeZone(req); - Utils.verifySuccess(resp.getStatus()); - this.zoneId = ZoneId.of(zoneId); - } - } diff --git a/client/src/main/java/org/apache/iotdb/cli/WinCli.java b/client/src/main/java/org/apache/iotdb/client/WinClient.java similarity index 97% rename from client/src/main/java/org/apache/iotdb/cli/WinCli.java rename to client/src/main/java/org/apache/iotdb/client/WinClient.java index ae4930484f7..a174e10379e 100644 --- a/client/src/main/java/org/apache/iotdb/cli/WinCli.java +++ b/client/src/main/java/org/apache/iotdb/client/WinClient.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.cli; +package org.apache.iotdb.client; import java.io.Console; import java.sql.DriverManager; @@ -33,7 +33,7 @@ import org.apache.iotdb.jdbc.Config; import org.apache.iotdb.jdbc.IoTDBConnection; import org.apache.thrift.TException; -public class WinCli extends AbstractCli { +public class WinClient extends AbstractClient { private static CommandLine commandLine; @@ -71,7 +71,7 @@ public class WinCli extends AbstractCli { private static String readPassword() { Console c = System.console(); - if (c == null) { // IN ECLIPSE IDE + if (c == null) { // IN ECLIENTPSE IDE print(IOTDB_CLI_PREFIX + "> please input password: "); Scanner scanner = new Scanner(System.in); return scanner.nextLine(); diff --git a/client/src/main/java/org/apache/iotdb/tool/ExportCsv.java b/client/src/main/java/org/apache/iotdb/tool/ExportCsv.java index 7b2c8ef237a..702d4b210f3 100644 --- a/client/src/main/java/org/apache/iotdb/tool/ExportCsv.java +++ b/client/src/main/java/org/apache/iotdb/tool/ExportCsv.java @@ -41,7 +41,7 @@ import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; -import org.apache.iotdb.cli.AbstractCli; +import org.apache.iotdb.client.AbstractClient; import org.apache.iotdb.exception.ArgsErrorException; import org.apache.iotdb.jdbc.Config; import org.apache.iotdb.jdbc.IoTDBConnection; @@ -322,7 +322,7 @@ public class ExportCsv extends AbstractCsvTool { switch (timeFormat) { case "default": long timestamp = rs.getLong(1); - String str = AbstractCli + String str = AbstractClient .parseLongToDateWithPrecision(DateTimeFormatter.ISO_OFFSET_DATE_TIME, timestamp, zoneId, TIMESTAMP_PRECISION); bw.write(str + ","); diff --git a/client/src/test/java/org/apache/iotdb/cli/AbstractCliIT.java b/client/src/test/java/org/apache/iotdb/cli/AbstractCliIT.java deleted file mode 100644 index 711f4f2d605..00000000000 --- a/client/src/test/java/org/apache/iotdb/cli/AbstractCliIT.java +++ /dev/null @@ -1,223 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.iotdb.cli; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.when; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.iotdb.cli.AbstractCli.OperationResult; -import org.apache.iotdb.exception.ArgsErrorException; -import org.apache.iotdb.jdbc.IoTDBConnection; -import org.apache.iotdb.jdbc.IoTDBDatabaseMetadata; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class AbstractCliIT { - private static Logger logger = LoggerFactory.getLogger(AbstractCliIT.class); - @Mock - private IoTDBConnection connection; - - @Mock - private IoTDBDatabaseMetadata databaseMetadata; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - when(connection.getMetaData()).thenReturn(databaseMetadata); - when(connection.getTimeZone()).thenReturn("Asia/Shanghai"); - when(databaseMetadata.getMetadataInJson()).thenReturn("test metadata"); - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testInit() { - AbstractCli.init(); - String[] keywords = {AbstractCli.HOST_ARGS, AbstractCli.HELP_ARGS, - AbstractCli.PORT_ARGS, - AbstractCli.PASSWORD_ARGS, AbstractCli.USERNAME_ARGS, AbstractCli.ISO8601_ARGS, - AbstractCli.MAX_PRINT_ROW_COUNT_ARGS,}; - for (String keyword : keywords) { - if (!AbstractCli.keywordSet.contains("-" + keyword)) { - logger.error(keyword); - fail(); - } - } - } - - @Test - public void testCheckRequiredArg() throws ParseException, ArgsErrorException { - Options options = AbstractCli.createOptions(); - CommandLineParser parser = new DefaultParser(); - String[] args = new String[]{"-u", "user1"}; - CommandLine commandLine = parser.parse(options, args); - String str = AbstractCli - .checkRequiredArg(AbstractCli.USERNAME_ARGS, AbstractCli.USERNAME_NAME, - commandLine, true, "root"); - assertEquals("user1", str); - - args = new String[]{"-u", "root",}; - commandLine = parser.parse(options, args); - str = AbstractCli - .checkRequiredArg(AbstractCli.HOST_ARGS, AbstractCli.HOST_NAME, commandLine, false, - "127.0.0.1"); - assertEquals("127.0.0.1", str); - try { - str = AbstractCli - .checkRequiredArg(AbstractCli.HOST_ARGS, AbstractCli.HOST_NAME, commandLine, true, - "127.0.0.1"); - } catch (ArgsErrorException e) { - assertEquals("IoTDB: Required values for option 'host' not provided", e.getMessage()); - } - try { - str = AbstractCli - .checkRequiredArg(AbstractCli.HOST_ARGS, AbstractCli.HOST_NAME, commandLine, - false, null); - } catch (ArgsErrorException e) { - assertEquals("IoTDB: Required values for option 'host' is null.", e.getMessage()); - } - } - - @Test - public void testRemovePasswordArgs() { - AbstractCli.init(); - String[] input = new String[]{"-h", "127.0.0.1", "-p", "6667", "-u", "root", "-pw", "root"}; - String[] res = new String[]{"-h", "127.0.0.1", "-p", "6667", "-u", "root", "-pw", "root"}; - isTwoStringArrayEqual(res, AbstractCli.removePasswordArgs(input)); - - input = new String[]{"-h", "127.0.0.1", "-p", "6667", "-pw", "root", "-u", "root"}; - res = new String[]{"-h", "127.0.0.1", "-p", "6667", "-pw", "root", "-u", "root"}; - isTwoStringArrayEqual(res, AbstractCli.removePasswordArgs(input)); - - input = new String[]{"-h", "127.0.0.1", "-p", "6667", "root", "-u", "root", "-pw"}; - res = new String[]{"-h", "127.0.0.1", "-p", "6667", "root", "-u", "root"}; - isTwoStringArrayEqual(res, AbstractCli.removePasswordArgs(input)); - - input = new String[]{"-h", "127.0.0.1", "-p", "6667", "-pw", "-u", "root"}; - res = new String[]{"-h", "127.0.0.1", "-p", "6667", "-u", "root"}; - isTwoStringArrayEqual(res, AbstractCli.removePasswordArgs(input)); - - input = new String[]{"-pw", "-h", "127.0.0.1", "-p", "6667", "root", "-u", "root"}; - res = new String[]{"-h", "127.0.0.1", "-p", "6667", "root", "-u", "root"}; - isTwoStringArrayEqual(res, AbstractCli.removePasswordArgs(input)); - - input = new String[]{}; - res = new String[]{}; - isTwoStringArrayEqual(res, AbstractCli.removePasswordArgs(input)); - } - - private void isTwoStringArrayEqual(String[] expected, String[] actual) { - for (int i = 0; i < expected.length; i++) { - assertEquals(expected[i], actual[i]); - } - } - - @Test - public void testHandleInputInputCmd() { - assertEquals(OperationResult.STOP_OPER, AbstractCli - .handleInputCmd(AbstractCli.EXIT_COMMAND, connection)); - assertEquals(OperationResult.STOP_OPER, AbstractCli - .handleInputCmd(AbstractCli.QUIT_COMMAND, connection)); - - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(AbstractCli.SHOW_METADATA_COMMAND, connection)); - - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(String.format("%s=", AbstractCli.SET_TIMESTAMP_DISPLAY), connection)); - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(String.format("%s=xxx", AbstractCli.SET_TIMESTAMP_DISPLAY), connection)); - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(String.format("%s=default", AbstractCli.SET_TIMESTAMP_DISPLAY), connection)); - testSetTimeFormat(); - - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(String.format("%s=", AbstractCli.SET_MAX_DISPLAY_NUM), connection)); - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(String.format("%s=xxx", AbstractCli.SET_MAX_DISPLAY_NUM),connection)); - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(String.format("%s=1", AbstractCli.SET_MAX_DISPLAY_NUM), connection)); - testSetMaxDisplayNumber(); - - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(AbstractCli.SHOW_TIMEZONE, connection)); - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(AbstractCli.SHOW_TIMESTAMP_DISPLAY, connection)); - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(AbstractCli.SHOW_FETCH_SIZE, connection)); - - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(String.format("%s=", AbstractCli.SET_TIME_ZONE), connection)); - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(String.format("%s=+08:00", AbstractCli.SET_TIME_ZONE), connection)); - - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(String.format("%s=", AbstractCli.SET_FETCH_SIZE), connection)); - assertEquals(OperationResult.CONTINUE_OPER, AbstractCli - .handleInputCmd(String.format("%s=111", AbstractCli.SET_FETCH_SIZE), connection)); - } - - private void testSetTimeFormat() { - AbstractCli.setTimeFormat("long"); - assertEquals(AbstractCli.maxTimeLength, AbstractCli.maxValueLength); - assertEquals(AbstractCli.formatTime, "%" + AbstractCli.maxTimeLength + "s|"); - - AbstractCli.setTimeFormat("number"); - assertEquals(AbstractCli.maxTimeLength, AbstractCli.maxValueLength); - assertEquals(AbstractCli.formatTime, "%" + AbstractCli.maxTimeLength + "s|"); - - AbstractCli.setTimeFormat("default"); - assertEquals(AbstractCli.ISO_DATETIME_LEN, AbstractCli.maxTimeLength); - assertEquals(AbstractCli.formatTime, "%" + AbstractCli.maxTimeLength + "s|"); - - AbstractCli.setTimeFormat("iso8601"); - assertEquals(AbstractCli.ISO_DATETIME_LEN, AbstractCli.maxTimeLength); - assertEquals(AbstractCli.formatTime, "%" + AbstractCli.maxTimeLength + "s|"); - - AbstractCli.setTimeFormat("yyyy-MM-dd HH:mm:ssZZ"); - assertEquals(AbstractCli.maxTimeLength, "yyyy-MM-dd HH:mm:ssZZ".length()); - assertEquals(AbstractCli.formatTime, "%" + AbstractCli.maxTimeLength + "s|"); - - AbstractCli.setTimeFormat("dd"); - assertEquals(AbstractCli.maxTimeLength, AbstractCli.TIMESTAMP_STR.length()); - assertEquals(AbstractCli.formatTime, "%" + AbstractCli.maxTimeLength + "s|"); - - } - - private void testSetMaxDisplayNumber() { - AbstractCli.setMaxDisplayNumber("10"); - assertEquals(10, AbstractCli.maxPrintRowCount); - AbstractCli.setMaxDisplayNumber("111111111111111"); - assertEquals(Integer.MAX_VALUE, AbstractCli.maxPrintRowCount); - AbstractCli.setMaxDisplayNumber("-10"); - assertEquals(Integer.MAX_VALUE, AbstractCli.maxPrintRowCount); - } -} diff --git a/client/src/test/java/org/apache/iotdb/client/AbstractClientIT.java b/client/src/test/java/org/apache/iotdb/client/AbstractClientIT.java new file mode 100644 index 00000000000..e9c6f15f9f2 --- /dev/null +++ b/client/src/test/java/org/apache/iotdb/client/AbstractClientIT.java @@ -0,0 +1,223 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.iotdb.client; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.when; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.iotdb.client.AbstractClient.OperationResult; +import org.apache.iotdb.exception.ArgsErrorException; +import org.apache.iotdb.jdbc.IoTDBConnection; +import org.apache.iotdb.jdbc.IoTDBDatabaseMetadata; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AbstractClientIT { + private static Logger logger = LoggerFactory.getLogger(AbstractClientIT.class); + @Mock + private IoTDBConnection connection; + + @Mock + private IoTDBDatabaseMetadata databaseMetadata; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + when(connection.getMetaData()).thenReturn(databaseMetadata); + when(connection.getTimeZone()).thenReturn("Asia/Shanghai"); + when(databaseMetadata.getMetadataInJson()).thenReturn("test metadata"); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testInit() { + AbstractClient.init(); + String[] keywords = {AbstractClient.HOST_ARGS, AbstractClient.HELP_ARGS, + AbstractClient.PORT_ARGS, + AbstractClient.PASSWORD_ARGS, AbstractClient.USERNAME_ARGS, AbstractClient.ISO8601_ARGS, + AbstractClient.MAX_PRINT_ROW_COUNT_ARGS,}; + for (String keyword : keywords) { + if (!AbstractClient.keywordSet.contains("-" + keyword)) { + logger.error(keyword); + fail(); + } + } + } + + @Test + public void testCheckRequiredArg() throws ParseException, ArgsErrorException { + Options options = AbstractClient.createOptions(); + CommandLineParser parser = new DefaultParser(); + String[] args = new String[]{"-u", "user1"}; + CommandLine commandLine = parser.parse(options, args); + String str = AbstractClient + .checkRequiredArg(AbstractClient.USERNAME_ARGS, AbstractClient.USERNAME_NAME, + commandLine, true, "root"); + assertEquals("user1", str); + + args = new String[]{"-u", "root",}; + commandLine = parser.parse(options, args); + str = AbstractClient + .checkRequiredArg(AbstractClient.HOST_ARGS, AbstractClient.HOST_NAME, commandLine, false, + "127.0.0.1"); + assertEquals("127.0.0.1", str); + try { + str = AbstractClient + .checkRequiredArg(AbstractClient.HOST_ARGS, AbstractClient.HOST_NAME, commandLine, true, + "127.0.0.1"); + } catch (ArgsErrorException e) { + assertEquals("IoTDB: Required values for option 'host' not provided", e.getMessage()); + } + try { + str = AbstractClient + .checkRequiredArg(AbstractClient.HOST_ARGS, AbstractClient.HOST_NAME, commandLine, + false, null); + } catch (ArgsErrorException e) { + assertEquals("IoTDB: Required values for option 'host' is null.", e.getMessage()); + } + } + + @Test + public void testRemovePasswordArgs() { + AbstractClient.init(); + String[] input = new String[]{"-h", "127.0.0.1", "-p", "6667", "-u", "root", "-pw", "root"}; + String[] res = new String[]{"-h", "127.0.0.1", "-p", "6667", "-u", "root", "-pw", "root"}; + isTwoStringArrayEqual(res, AbstractClient.removePasswordArgs(input)); + + input = new String[]{"-h", "127.0.0.1", "-p", "6667", "-pw", "root", "-u", "root"}; + res = new String[]{"-h", "127.0.0.1", "-p", "6667", "-pw", "root", "-u", "root"}; + isTwoStringArrayEqual(res, AbstractClient.removePasswordArgs(input)); + + input = new String[]{"-h", "127.0.0.1", "-p", "6667", "root", "-u", "root", "-pw"}; + res = new String[]{"-h", "127.0.0.1", "-p", "6667", "root", "-u", "root"}; + isTwoStringArrayEqual(res, AbstractClient.removePasswordArgs(input)); + + input = new String[]{"-h", "127.0.0.1", "-p", "6667", "-pw", "-u", "root"}; + res = new String[]{"-h", "127.0.0.1", "-p", "6667", "-u", "root"}; + isTwoStringArrayEqual(res, AbstractClient.removePasswordArgs(input)); + + input = new String[]{"-pw", "-h", "127.0.0.1", "-p", "6667", "root", "-u", "root"}; + res = new String[]{"-h", "127.0.0.1", "-p", "6667", "root", "-u", "root"}; + isTwoStringArrayEqual(res, AbstractClient.removePasswordArgs(input)); + + input = new String[]{}; + res = new String[]{}; + isTwoStringArrayEqual(res, AbstractClient.removePasswordArgs(input)); + } + + private void isTwoStringArrayEqual(String[] expected, String[] actual) { + for (int i = 0; i < expected.length; i++) { + assertEquals(expected[i], actual[i]); + } + } + + @Test + public void testHandleInputInputCmd() { + assertEquals(OperationResult.STOP_OPER, AbstractClient + .handleInputCmd(AbstractClient.EXIT_COMMAND, connection)); + assertEquals(OperationResult.STOP_OPER, AbstractClient + .handleInputCmd(AbstractClient.QUIT_COMMAND, connection)); + + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(AbstractClient.SHOW_METADATA_COMMAND, connection)); + + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(String.format("%s=", AbstractClient.SET_TIMESTAMP_DISPLAY), connection)); + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(String.format("%s=xxx", AbstractClient.SET_TIMESTAMP_DISPLAY), connection)); + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(String.format("%s=default", AbstractClient.SET_TIMESTAMP_DISPLAY), connection)); + testSetTimeFormat(); + + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(String.format("%s=", AbstractClient.SET_MAX_DISPLAY_NUM), connection)); + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(String.format("%s=xxx", AbstractClient.SET_MAX_DISPLAY_NUM),connection)); + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(String.format("%s=1", AbstractClient.SET_MAX_DISPLAY_NUM), connection)); + testSetMaxDisplayNumber(); + + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(AbstractClient.SHOW_TIMEZONE, connection)); + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(AbstractClient.SHOW_TIMESTAMP_DISPLAY, connection)); + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(AbstractClient.SHOW_FETCH_SIZE, connection)); + + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(String.format("%s=", AbstractClient.SET_TIME_ZONE), connection)); + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(String.format("%s=+08:00", AbstractClient.SET_TIME_ZONE), connection)); + + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(String.format("%s=", AbstractClient.SET_FETCH_SIZE), connection)); + assertEquals(OperationResult.CONTINUE_OPER, AbstractClient + .handleInputCmd(String.format("%s=111", AbstractClient.SET_FETCH_SIZE), connection)); + } + + private void testSetTimeFormat() { + AbstractClient.setTimeFormat("long"); + assertEquals(AbstractClient.maxTimeLength, AbstractClient.maxValueLength); + assertEquals(AbstractClient.formatTime, "%" + AbstractClient.maxTimeLength + "s|"); + + AbstractClient.setTimeFormat("number"); + assertEquals(AbstractClient.maxTimeLength, AbstractClient.maxValueLength); + assertEquals(AbstractClient.formatTime, "%" + AbstractClient.maxTimeLength + "s|"); + + AbstractClient.setTimeFormat("default"); + assertEquals(AbstractClient.ISO_DATETIME_LEN, AbstractClient.maxTimeLength); + assertEquals(AbstractClient.formatTime, "%" + AbstractClient.maxTimeLength + "s|"); + + AbstractClient.setTimeFormat("iso8601"); + assertEquals(AbstractClient.ISO_DATETIME_LEN, AbstractClient.maxTimeLength); + assertEquals(AbstractClient.formatTime, "%" + AbstractClient.maxTimeLength + "s|"); + + AbstractClient.setTimeFormat("yyyy-MM-dd HH:mm:ssZZ"); + assertEquals(AbstractClient.maxTimeLength, "yyyy-MM-dd HH:mm:ssZZ".length()); + assertEquals(AbstractClient.formatTime, "%" + AbstractClient.maxTimeLength + "s|"); + + AbstractClient.setTimeFormat("dd"); + assertEquals(AbstractClient.maxTimeLength, AbstractClient.TIMESTAMP_STR.length()); + assertEquals(AbstractClient.formatTime, "%" + AbstractClient.maxTimeLength + "s|"); + + } + + private void testSetMaxDisplayNumber() { + AbstractClient.setMaxDisplayNumber("10"); + assertEquals(10, AbstractClient.maxPrintRowCount); + AbstractClient.setMaxDisplayNumber("111111111111111"); + assertEquals(Integer.MAX_VALUE, AbstractClient.maxPrintRowCount); + AbstractClient.setMaxDisplayNumber("-10"); + assertEquals(Integer.MAX_VALUE, AbstractClient.maxPrintRowCount); + } +} diff --git a/client/src/test/java/org/apache/iotdb/cli/AbstractScript.java b/client/src/test/java/org/apache/iotdb/client/AbstractScript.java similarity index 98% rename from client/src/test/java/org/apache/iotdb/cli/AbstractScript.java rename to client/src/test/java/org/apache/iotdb/client/AbstractScript.java index e538534f75d..79c5daf19e8 100644 --- a/client/src/test/java/org/apache/iotdb/cli/AbstractScript.java +++ b/client/src/test/java/org/apache/iotdb/client/AbstractScript.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.cli; +package org.apache.iotdb.client; import static org.junit.Assert.assertEquals; diff --git a/client/src/test/java/org/apache/iotdb/cli/StartCliScriptIT.java b/client/src/test/java/org/apache/iotdb/client/StartClientScriptIT.java similarity index 94% rename from client/src/test/java/org/apache/iotdb/cli/StartCliScriptIT.java rename to client/src/test/java/org/apache/iotdb/client/StartClientScriptIT.java index 045f0ab3d8a..28a291701eb 100644 --- a/client/src/test/java/org/apache/iotdb/cli/StartCliScriptIT.java +++ b/client/src/test/java/org/apache/iotdb/client/StartClientScriptIT.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.cli; +package org.apache.iotdb.client; import java.io.File; import java.io.IOException; @@ -25,7 +25,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -public class StartCliScriptIT extends AbstractScript { +public class StartClientScriptIT extends AbstractScript { @Before public void setUp() throws Exception { @@ -47,12 +47,12 @@ public class StartCliScriptIT extends AbstractScript { @Override protected void testOnWindows() throws IOException { - final String[] output = {"````````````````````````", "Starting IoTDB Cli", + final String[] output = {"````````````````````````", "Starting IoTDB Client", "````````````````````````", "IoTDB> Connection Error, please check whether the network is available or the server has started. Host is 127.0.0.1, port is 6668."}; String dir = getCliPath(); ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", - dir + File.separator + "sbin" + File.separator + "start-cli.bat", + dir + File.separator + "sbin" + File.separator + "start-client.bat", "-h", "127.0.0.1", "-p", "6668", "-u", "root", "-pw", "root"); testOutput(builder, output); @@ -64,7 +64,7 @@ public class StartCliScriptIT extends AbstractScript { "IoTDB> Connection Error, please check whether the network is available or the server has started. Host is 127.0.0.1, port is 6668."}; String dir = getCliPath(); ProcessBuilder builder = new ProcessBuilder("sh", - dir + File.separator + "sbin" + File.separator + "start-cli.sh", + dir + File.separator + "sbin" + File.separator + "start-client.sh", "-h", "127.0.0.1", "-p", "6668", "-u", "root", "-pw", "root"); testOutput(builder, output); diff --git a/client/src/test/java/org/apache/iotdb/tool/ExportCsvTestIT.java b/client/src/test/java/org/apache/iotdb/tool/ExportCsvTestIT.java index 4b10f22c791..7d0fd202f75 100644 --- a/client/src/test/java/org/apache/iotdb/tool/ExportCsvTestIT.java +++ b/client/src/test/java/org/apache/iotdb/tool/ExportCsvTestIT.java @@ -20,7 +20,7 @@ package org.apache.iotdb.tool; import java.io.File; import java.io.IOException; -import org.apache.iotdb.cli.AbstractScript; +import org.apache.iotdb.client.AbstractScript; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/client/src/test/java/org/apache/iotdb/tool/ImportCsvTestIT.java b/client/src/test/java/org/apache/iotdb/tool/ImportCsvTestIT.java index 1286caa4f11..95863b49271 100644 --- a/client/src/test/java/org/apache/iotdb/tool/ImportCsvTestIT.java +++ b/client/src/test/java/org/apache/iotdb/tool/ImportCsvTestIT.java @@ -20,7 +20,7 @@ package org.apache.iotdb.tool; import java.io.File; import java.io.IOException; -import org.apache.iotdb.cli.AbstractScript; +import org.apache.iotdb.client.AbstractScript; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/docs/Development.md b/docs/Development.md index ef5589a1e83..d3d026d51e3 100644 --- a/docs/Development.md +++ b/docs/Development.md @@ -74,8 +74,8 @@ you can just choose menu "import" -> "Maven" -> "Existing Maven Projects". ## Debugging IoTDB The main class of IoTDB server is `org.apache.iotdb.db.service.IoTDB`. -The main class of IoTDB cli is `org.apache.iotdb.cli.Cli` -(or `org.apache.iotdb.cli.WinCli` on Win OS). +The main class of IoTDB cli is `org.apache.iotdb.client.Client` +(or `org.apache.iotdb.client.WinClient` on Win OS). You can run/debug IoTDB by using the two classes as the entrance. diff --git a/docs/Documentation-CHN/UserGuide/1-Overview/3-Scenario.md b/docs/Documentation-CHN/UserGuide/1-Overview/3-Scenario.md index 95176b33a84..79fe86e82db 100644 --- a/docs/Documentation-CHN/UserGuide/1-Overview/3-Scenario.md +++ b/docs/Documentation-CHN/UserGuide/1-Overview/3-Scenario.md @@ -57,7 +57,7 @@ 为了保证机械手的监控数据能够及时监控和分析,公司需要收集这些机械手传感器信息,将其发送至可以连接外部网络的服务器上,而后将原始数据信息上传到数据中心进行复杂的计算和分析。 -此时,可以采用IoTDB套件中的IoTDB、IoTDB-CLI工具、TsFileSync工具和Hadoop/Spark集成组件等。将IoTDB服务器安装在工厂连接外网的服务器上,用户接收机械手传输的数据并将数据上传到数据中心。将IoTDB-CLI工具安装在每一个连接工厂内网的机械手上,用于将传感器产生的实时数据上传到工厂内部服务器。再使用TsFileSync工具将原始数据上传到数据中心。此外还需要部署Hadoop/Spark集群用于数据中心端的数据存储和分析。如图1.6中间场景所示。 +此时,可以采用IoTDB套件中的IoTDB、IoTDB-Client工具、TsFileSync工具和Hadoop/Spark集成组件等。将IoTDB服务器安装在工厂连接外网的服务器上,用户接收机械手传输的数据并将数据上传到数据中心。将IoTDB-Client工具安装在每一个连接工厂内网的机械手上,用于将传感器产生的实时数据上传到工厂内部服务器。再使用TsFileSync工具将原始数据上传到数据中心。此外还需要部署Hadoop/Spark集群用于数据中心端的数据存储和分析。如图1.6中间场景所示。 @@ -71,7 +71,7 @@ 为了能够实时接收汽车传感器所采集的物联网数据,公司需要在车辆行驶的过程中将传感器数据通过窄带物联网实时发送至数据中心,而后在数据中心的服务器上进行复杂的计算和分析。 -此时,可以采用IoTDB套件中的IoTDB、IoTDB-CLI和Hadoop/Spark集成组件等。将IoTDB-CLI工具安装在每一辆车联网内的车辆上,使用IoTDB-JDBC工具将数据直接传回数据中心的服务器。 +此时,可以采用IoTDB套件中的IoTDB、IoTDB-Client和Hadoop/Spark集成组件等。将IoTDB-Client工具安装在每一辆车联网内的车辆上,使用IoTDB-JDBC工具将数据直接传回数据中心的服务器。 此外还需要部署Hadoop/Spark集群用于数据中心端的数据存储和分析。如图1.8所示。 diff --git a/docs/Documentation-CHN/UserGuide/7-Client API/1-Client API.md b/docs/Documentation-CHN/UserGuide/7-Session API/1-Session API.md similarity index 65% rename from docs/Documentation-CHN/UserGuide/7-Client API/1-Client API.md rename to docs/Documentation-CHN/UserGuide/7-Session API/1-Session API.md index 52a99a61e6a..b770c320c18 100644 --- a/docs/Documentation-CHN/UserGuide/7-Client API/1-Client API.md +++ b/docs/Documentation-CHN/UserGuide/7-Session API/1-Session API.md @@ -19,7 +19,7 @@ --> -# 第7章: JDBC API +# 第7章: Session API # 使用方式 @@ -28,33 +28,30 @@ * JDK >= 1.8 * Maven >= 3.0 -## 只打包 Client 模块 - -In root directory: -> mvn clean package -pl client -am -Dmaven.test.skip=true - ## 安装到本地 maven 库 In root directory: -> mvn clean install -pl client -am -Dmaven.test.skip=true +> mvn clean install -pl session -am -Dmaven.test.skip=true -## 在 maven 中使用 Client 接口 +## 在 maven 中使用 session 接口 ``` org.apache.iotdb - iotdb-client + iotdb-session 0.9.0-SNAPSHOT ``` - -## Client 示例 +## Session 接口使用示例 ```Java +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; import org.apache.iotdb.session.Session; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding; @@ -62,9 +59,20 @@ import org.apache.iotdb.tsfile.write.record.RowBatch; import org.apache.iotdb.tsfile.write.schema.MeasurementSchema; import org.apache.iotdb.tsfile.write.schema.Schema; - public static void main(String[] args) { - Client client = new Client("127.0.0.1", 6667, "root", "root"); - client.open(); + public static void main(String[] args) throws ClassNotFoundException { + Class.forName("org.apache.iotdb.jdbc.IoTDBDriver"); + try (Connection connection = DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root"); + Statement statement = connection.createStatement()) { + statement.execute("SET STORAGE GROUP TO root.sg1"); + statement.execute("CREATE TIMESERIES root.sg1.d1.s1 WITH DATATYPE=INT64, ENCODING=RLE"); + statement.execute("CREATE TIMESERIES root.sg1.d1.s2 WITH DATATYPE=INT64, ENCODING=RLE"); + statement.execute("CREATE TIMESERIES root.sg1.d1.s3 WITH DATATYPE=INT64, ENCODING=RLE"); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + + Session session = new Session("127.0.0.1", 6667, "root", "root"); + session.open(); Schema schema = new Schema(); schema.registerMeasurement(new MeasurementSchema("s1", TSDataType.INT64, TSEncoding.RLE)); @@ -76,7 +84,7 @@ import org.apache.iotdb.tsfile.write.schema.Schema; long[] timestamps = rowBatch.timestamps; Object[] values = rowBatch.values; - for (long time = 0; time < 1000; time++) { + for (long time = 0; time < 30000; time++) { int row = rowBatch.batchSize++; timestamps[row] = time; for (int i = 0; i < 3; i++) { @@ -88,14 +96,14 @@ import org.apache.iotdb.tsfile.write.schema.Schema; rowBatch.reset(); } } - + if (rowBatch.batchSize != 0) { session.insertBatch(rowBatch); rowBatch.reset(); } - client.close(); + session.close(); } ``` -> The code is in example/client/src/main/java/org/apache/iotdb/client/ClientExample.java \ No newline at end of file +> The code is in example/session/src/main/java/org/apache/iotdb/session/SessionExample.java \ No newline at end of file diff --git a/docs/Documentation-CHN/UserGuide/9-Tools-Cli.md b/docs/Documentation-CHN/UserGuide/9-Tools-Cli.md index 79007c5838b..f4e0c1e309b 100644 --- a/docs/Documentation-CHN/UserGuide/9-Tools-Cli.md +++ b/docs/Documentation-CHN/UserGuide/9-Tools-Cli.md @@ -29,7 +29,7 @@ # Cli / Shell工具 -IOTDB为用户提供CLI/Shell工具用于启动客户端和服务端程序。下面介绍每个CLI/Shell工具的运行方式和相关参数。 +IOTDB为用户提供Client/Shell工具用于启动客户端和服务端程序。下面介绍每个Client/Shell工具的运行方式和相关参数。 > \$IOTDB\_HOME表示IoTDB的安装目录所在路径。 ## Cli / Shell运行方式 @@ -91,7 +91,7 @@ Windows系统启动命令如下: 为了避免SQL语句和其他参数混淆,现在只支持-e参数作为最后的参数使用。 -针对CLI/Shell工具的-e参数用法如下: +针对Client/Shell工具的-e参数用法如下: ``` Shell > ./sbin/start-cli.sh -h {host} -p {port} -u {user} -pw {password} -e {sql for iotdb} @@ -109,7 +109,7 @@ Windows系统启动命令如下: 4.查询验证数据是否插入成功 -那么通过使用CLI/Shell工具的-e参数,可以采用如下的脚本: +那么通过使用Client/Shell工具的-e参数,可以采用如下的脚本: ``` # !/bin/bash diff --git a/docs/Documentation/Frequently asked questions.md b/docs/Documentation/Frequently asked questions.md index f9f0ed53a6c..096e4decfa1 100644 --- a/docs/Documentation/Frequently asked questions.md +++ b/docs/Documentation/Frequently asked questions.md @@ -31,7 +31,7 @@ - Can I use Hadoop and Spark to read TsFile in IoTDB? - How does IoTDB handle duplicate points? - How can I tell what type of the specific timeseries? - - How can I change IoTDB's CLI time display format? + - How can I change IoTDB's Client time display format? # Frequently Asked Questions @@ -137,9 +137,9 @@ Otherwise, you can also use wildcard in timeseries path: IoTDB> show timeseries root.fit.d1.* ``` -## How can I change IoTDB's CLI time display format? +## How can I change IoTDB's Client time display format? -The default IoTDB's CLI time display format is human readable (e.g. ```1970-01-01T08:00:00.001```), if you want to display time in timestamp type or other readable format, add parameter ```-disableIS08601``` in start command: +The default IoTDB's Client time display format is human readable (e.g. ```1970-01-01T08:00:00.001```), if you want to display time in timestamp type or other readable format, add parameter ```-disableIS08601``` in start command: ``` > $IOTDB_CLI_HOME/sbin/start-cli.sh -h 127.0.0.1 -p 6667 -u root -pw root -disableIS08601 diff --git a/docs/Documentation/UserGuide/1-Overview/3-Scenario.md b/docs/Documentation/UserGuide/1-Overview/3-Scenario.md index 879c5cbbceb..bac5ec91b80 100644 --- a/docs/Documentation/UserGuide/1-Overview/3-Scenario.md +++ b/docs/Documentation/UserGuide/1-Overview/3-Scenario.md @@ -61,7 +61,7 @@ In order to ensure that the data of the robot can be monitored and analyzed in t -At this point, IoTDB, IoTDB-CLI tools, TsFileSync tools, and Hadoop/Spark integration components in the IoTDB suite can be used. IoTDB-CLI tool is installed on the robot and each of them is connected to the LAN of the factory. When sensors generate real-time data, the data will be uploaded to the server in the factory. The IoTDB server and TsFileSync is installed on the server connected to the external network. Once triggered, the data on the server will be upload to the data center. In addition, Hadoop/Spark clusters need to be deployed for data storage and analysis on the data center side. As shown in Figure 1.6. Figure 1.7 shows the architecture at this time. +At this point, IoTDB, IoTDB-Client tools, TsFileSync tools, and Hadoop/Spark integration components in the IoTDB suite can be used. IoTDB-Client tool is installed on the robot and each of them is connected to the LAN of the factory. When sensors generate real-time data, the data will be uploaded to the server in the factory. The IoTDB server and TsFileSync is installed on the server connected to the external network. Once triggered, the data on the server will be upload to the data center. In addition, Hadoop/Spark clusters need to be deployed for data storage and analysis on the data center side. As shown in Figure 1.6. Figure 1.7 shows the architecture at this time. @@ -71,7 +71,7 @@ A car company installed sensors on its cars to collect monitoring information su In order to receive the IoT data collected by the car sensor in real time, the company needs to send the sensor data to the data center in real time through the narrowband IoT while the vehicle is running. Thus, they can perform complex calculations and analysis on the server in the data center. -At this point, IoTDB, IoTDB-CLI, and Hadoop/Spark integration components in the IoTDB suite can be used. IoTDB-CLI tool is installed on each car and use IoTDB-JDBC tool to send data directly back to the server in the data center. +At this point, IoTDB, IoTDB-Client, and Hadoop/Spark integration components in the IoTDB suite can be used. IoTDB-Client tool is installed on each car and use IoTDB-JDBC tool to send data directly back to the server in the data center. In addition, Hadoop/Spark clusters need to be deployed for data storage and analysis on the data center side. As shown in Figure 1.8. diff --git a/docs/Documentation/UserGuide/3-Operation Manual/3-Data Import.md b/docs/Documentation/UserGuide/3-Operation Manual/3-Data Import.md index 78740162aff..542e8ed4b08 100644 --- a/docs/Documentation/UserGuide/3-Operation Manual/3-Data Import.md +++ b/docs/Documentation/UserGuide/3-Operation Manual/3-Data Import.md @@ -28,7 +28,7 @@ This feature is not supported in version 0.7.0. ### Import Real-time Data -IoTDB provides users with a variety of ways to insert real-time data, such as directly inputting [INSERT SQL statement](/#/Documents/0.8.0/chap5/sec1) in [Cli/Shell tools](/#/Tools/Cli), or using [Java JDBC](/#/Documents/0.8.0/chap6/sec1) to perform single or batch execution of [INSERT SQL statement](/#/Documents/0.8.0/chap5/sec1). +IoTDB provides users with a variety of ways to insert real-time data, such as directly inputting [INSERT SQL statement](/#/Documents/0.8.0/chap5/sec1) in [Client/Shell tools](/#/Tools/Client), or using [Java JDBC](/#/Documents/0.8.0/chap6/sec1) to perform single or batch execution of [INSERT SQL statement](/#/Documents/0.8.0/chap5/sec1). This section mainly introduces the use of [INSERT SQL statement](/#/Documents/0.8.0/chap5/sec1) for real-time data import in the scenario. See Section 5.1 for a detailed syntax of [INSERT SQL statement](/#/Documents/0.8.0/chap5/sec1). diff --git a/docs/Documentation/UserGuide/5-IoTDB SQL Documentation/1-IoTDB Query Statement.md b/docs/Documentation/UserGuide/5-IoTDB SQL Documentation/1-IoTDB Query Statement.md index a56239760a0..9b34bb4f2c5 100644 --- a/docs/Documentation/UserGuide/5-IoTDB SQL Documentation/1-IoTDB Query Statement.md +++ b/docs/Documentation/UserGuide/5-IoTDB SQL Documentation/1-IoTDB Query Statement.md @@ -74,7 +74,7 @@ Eg: IoTDB > DELETE TIMESERIES root.ln.wf01.wt01.* ``` SHOW TIMESERIES Eg: IoTDB > SHOW TIMESERIES -Note: This statement can only be used in IoTDB Cli. If you need to show all timeseries in JDBC, please use `DataBaseMetadata` interface. +Note: This statement can only be used in IoTDB Client. If you need to show all timeseries in JDBC, please use `DataBaseMetadata` interface. ``` * Show Specific Timeseries Statement @@ -86,7 +86,7 @@ Eg: IoTDB > SHOW TIMESERIES root.ln Eg: IoTDB > SHOW TIMESERIES root.ln.*.*.status Eg: IoTDB > SHOW TIMESERIES root.ln.wf01.wt01.status Note: The path can be prefix path, star path or timeseries path -Note: This statement can be used in IoTDB Cli and JDBC. +Note: This statement can be used in IoTDB Client and JDBC. ``` * Show Storage Group Statement @@ -94,7 +94,7 @@ Note: This statement can be used in IoTDB Cli and JDBC. ``` SHOW STORAGE GROUP Eg: IoTDB > SHOW STORAGE GROUP -Note: This statement can be used in IoTDB Cli and JDBC. +Note: This statement can be used in IoTDB Client and JDBC. ``` ### Data Management Statement diff --git a/docs/Documentation/UserGuide/6-JDBC API/1-JDBC API.md b/docs/Documentation/UserGuide/6-JDBC API/1-JDBC API.md index 753b2f29703..d1c865f7f7e 100644 --- a/docs/Documentation/UserGuide/6-JDBC API/1-JDBC API.md +++ b/docs/Documentation/UserGuide/6-JDBC API/1-JDBC API.md @@ -19,7 +19,7 @@ --> -# Chaper6: JDBC API +# Chapter6: JDBC API # Usage @@ -57,7 +57,7 @@ This chapter provides an example of how to open a database connection, execute a Requires that you include the packages containing the JDBC classes needed for database programming. -**NOTE: For faster insertion, the insertBatch() in Client is recommended.** +**NOTE: For faster insertion, the insertBatch() in Session is recommended.** ```Java import java.sql.*; diff --git a/docs/Documentation/UserGuide/7-Client API/1-Client API.md b/docs/Documentation/UserGuide/7-Session API/1-Session API.md similarity index 69% rename from docs/Documentation/UserGuide/7-Client API/1-Client API.md rename to docs/Documentation/UserGuide/7-Session API/1-Session API.md index f96476efc00..2bfbe28bcfd 100644 --- a/docs/Documentation/UserGuide/7-Client API/1-Client API.md +++ b/docs/Documentation/UserGuide/7-Session API/1-Session API.md @@ -19,7 +19,7 @@ --> -# Chaper7: JDBC API +# Chapter7: Session API # Usage @@ -38,7 +38,7 @@ In root directory: In root directory: > mvn clean install -pl client -am -Dmaven.test.skip=true -## Using IoTDB Client with Maven +## Using IoTDB Session with Maven ``` @@ -51,23 +51,37 @@ In root directory: ``` -## Examples with Client +## Examples with Session This chapter provides an example of how to open an IoTDB session, execute a batch insertion. Requires that you include the packages containing the Client classes needed for database programming. ```Java -import org.apache.iotdb.client.Client; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; +import org.apache.iotdb.session.Session; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding; import org.apache.iotdb.tsfile.write.record.RowBatch; import org.apache.iotdb.tsfile.write.schema.MeasurementSchema; import org.apache.iotdb.tsfile.write.schema.Schema; - public static void main(String[] args) { - Client client = new Client("127.0.0.1", 6667, "root", "root"); - client.open(); + public static void main(String[] args) throws ClassNotFoundException { + Class.forName("org.apache.iotdb.jdbc.IoTDBDriver"); + try (Connection connection = DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root"); + Statement statement = connection.createStatement()) { + statement.execute("SET STORAGE GROUP TO root.sg1"); + statement.execute("CREATE TIMESERIES root.sg1.d1.s1 WITH DATATYPE=INT64, ENCODING=RLE"); + statement.execute("CREATE TIMESERIES root.sg1.d1.s2 WITH DATATYPE=INT64, ENCODING=RLE"); + statement.execute("CREATE TIMESERIES root.sg1.d1.s3 WITH DATATYPE=INT64, ENCODING=RLE"); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + + Session session = new Session("127.0.0.1", 6667, "root", "root"); + session.open(); Schema schema = new Schema(); schema.registerMeasurement(new MeasurementSchema("s1", TSDataType.INT64, TSEncoding.RLE)); @@ -79,7 +93,7 @@ import org.apache.iotdb.tsfile.write.schema.Schema; long[] timestamps = rowBatch.timestamps; Object[] values = rowBatch.values; - for (long time = 0; time < 1000; time++) { + for (long time = 0; time < 30000; time++) { int row = rowBatch.batchSize++; timestamps[row] = time; for (int i = 0; i < 3; i++) { @@ -91,14 +105,14 @@ import org.apache.iotdb.tsfile.write.schema.Schema; rowBatch.reset(); } } - + if (rowBatch.batchSize != 0) { session.insertBatch(rowBatch); rowBatch.reset(); } - client.close(); + session.close(); } ``` -> The code is in example/client/src/main/java/org/apache/iotdb/client/ClientExample.java \ No newline at end of file +> The code is in example/session/src/main/java/org/apache/iotdb/session/SessionExample.java \ No newline at end of file diff --git a/example/pom.xml b/example/pom.xml index e621db00c67..4750be31d47 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -36,7 +36,7 @@ kafka rocketmq - client + session tsfile diff --git a/example/client/pom.xml b/example/session/pom.xml similarity index 97% rename from example/client/pom.xml rename to example/session/pom.xml index 2cdc6c3c000..8b1b2152f9b 100644 --- a/example/client/pom.xml +++ b/example/session/pom.xml @@ -36,7 +36,7 @@ org.apache.iotdb - iotdb-client + iotdb-session 0.9.0-SNAPSHOT diff --git a/example/client/src/main/java/org/apache/iotdb/client/JDBCExample.java b/example/session/src/main/java/org/apache/iotdb/JDBCExample.java similarity index 88% rename from example/client/src/main/java/org/apache/iotdb/client/JDBCExample.java rename to example/session/src/main/java/org/apache/iotdb/JDBCExample.java index 89e4c47489c..327146776fb 100644 --- a/example/client/src/main/java/org/apache/iotdb/client/JDBCExample.java +++ b/example/session/src/main/java/org/apache/iotdb/JDBCExample.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.client; +package org.apache.iotdb; import java.sql.Connection; import java.sql.DriverManager; @@ -29,10 +29,8 @@ public class JDBCExample { public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("org.apache.iotdb.jdbc.IoTDBDriver"); - Connection connection = null; - try { - connection = DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root"); - Statement statement = connection.createStatement(); + try (Connection connection = DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root"); + Statement statement = connection.createStatement()) { statement.execute("SET STORAGE GROUP TO root.sg1"); statement.execute("CREATE TIMESERIES root.sg1.d1.s1 WITH DATATYPE=INT64, ENCODING=RLE"); statement.execute("CREATE TIMESERIES root.sg1.d1.s2 WITH DATATYPE=INT64, ENCODING=RLE"); @@ -54,9 +52,6 @@ public class JDBCExample { } System.out.println(builder); } - statement.close(); - } finally { - connection.close(); } } } diff --git a/example/client/src/main/java/org/apache/iotdb/client/ClientExample.java b/example/session/src/main/java/org/apache/iotdb/SessionExample.java similarity index 88% rename from example/client/src/main/java/org/apache/iotdb/client/ClientExample.java rename to example/session/src/main/java/org/apache/iotdb/SessionExample.java index 82d0f5ce30d..07ef3487dae 100644 --- a/example/client/src/main/java/org/apache/iotdb/client/ClientExample.java +++ b/example/session/src/main/java/org/apache/iotdb/SessionExample.java @@ -16,11 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.client; +package org.apache.iotdb; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; +import org.apache.iotdb.session.Session; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding; import org.apache.iotdb.tsfile.write.record.RowBatch; @@ -37,23 +38,21 @@ import org.apache.iotdb.tsfile.write.schema.Schema; * CREATE TIMESERIES root.sg1.d1.s2 WITH DATATYPE=FLOAT, ENCODING=RLE * CREATE TIMESERIES root.sg1.d1.s3 WITH DATATYPE=FLOAT, ENCODING=RLE */ -public class ClientExample { +public class SessionExample { public static void main(String[] args) throws ClassNotFoundException { Class.forName("org.apache.iotdb.jdbc.IoTDBDriver"); - Connection connection = null; - try { - connection = DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root"); - Statement statement = connection.createStatement(); + try (Connection connection = DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root"); + Statement statement = connection.createStatement()) { statement.execute("SET STORAGE GROUP TO root.sg1"); statement.execute("CREATE TIMESERIES root.sg1.d1.s1 WITH DATATYPE=INT64, ENCODING=RLE"); statement.execute("CREATE TIMESERIES root.sg1.d1.s2 WITH DATATYPE=INT64, ENCODING=RLE"); statement.execute("CREATE TIMESERIES root.sg1.d1.s3 WITH DATATYPE=INT64, ENCODING=RLE"); } catch (Exception e) { - + System.out.println(e.getMessage()); } - Client session = new Client("127.0.0.1", 6667, "root", "root"); + Session session = new Session("127.0.0.1", 6667, "root", "root"); session.open(); Schema schema = new Schema(); diff --git a/pom.xml b/pom.xml index 0073930ee1e..d68980d1cac 100644 --- a/pom.xml +++ b/pom.xml @@ -388,6 +388,7 @@ spark-tsfile distribution + session diff --git a/server/src/main/antlr3/org/apache/iotdb/db/sql/parse/TSParser.g b/server/src/main/antlr3/org/apache/iotdb/db/sql/parse/TSParser.g index e53c4fc41ab..aa5bc28d073 100644 --- a/server/src/main/antlr3/org/apache/iotdb/db/sql/parse/TSParser.g +++ b/server/src/main/antlr3/org/apache/iotdb/db/sql/parse/TSParser.g @@ -119,7 +119,7 @@ ArrayList errors = new ArrayList(); private static HashMap xlateMap; static { - //this is used to support auto completion in CLI + //this is used to support auto completion in Client xlateMap = new HashMap(); // Keywords diff --git a/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java b/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java index d7883cdaab1..23454222f06 100644 --- a/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java +++ b/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java @@ -60,7 +60,7 @@ public class MemUtils { case BOOLEAN: memSize += 8L + 1L; break; case TEXT: - memSize += 8L + insertPlan.getValues()[i].length() * 2; break; + memSize += 8L + insertPlan.getValues()[i].length(); break; default: memSize += 8L + 8L; } @@ -85,7 +85,7 @@ public class MemUtils { case TEXT: memSize += batchInsertPlan.getRowCount() * 8L; for (int j = 0; j < batchInsertPlan.getRowCount(); j++) { - memSize += ((Binary[]) batchInsertPlan.getColumns()[i])[j].getLength() * 2; + memSize += ((Binary[]) batchInsertPlan.getColumns()[i])[j].getLength(); } break; default: diff --git a/service-rpc/src/main/thrift/rpc.thrift b/service-rpc/src/main/thrift/rpc.thrift index 2ea6c1d4886..a96284bfe6c 100644 --- a/service-rpc/src/main/thrift/rpc.thrift +++ b/service-rpc/src/main/thrift/rpc.thrift @@ -37,7 +37,7 @@ struct TS_Status { 2: optional list infoMessages // If status is ERROR, then the following fields may be set - 3: optional string sqlState // as defined in the ISO/IEF CLI specification + 3: optional string sqlState // as defined in the ISO/IEF CLIENT specification 4: optional i32 errorCode // internal error code 5: optional string errorMessage } diff --git a/session/pom.xml b/session/pom.xml new file mode 100644 index 00000000000..0fcdaa9a10e --- /dev/null +++ b/session/pom.xml @@ -0,0 +1,62 @@ + + + + + iotdb-parent + org.apache.iotdb + 0.9.0-SNAPSHOT + + 4.0.0 + + iotdb-session + + IoTDB Session + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + + + UTF-8 + 1.7 + 1.7 + + + + + org.apache.iotdb + iotdb-jdbc + 0.9.0-SNAPSHOT + + + + diff --git a/client/src/main/java/org/apache/iotdb/exception/IoTDBSessionException.java b/session/src/main/java/org/apache/iotdb/exception/IoTDBSessionException.java similarity index 100% rename from client/src/main/java/org/apache/iotdb/exception/IoTDBSessionException.java rename to session/src/main/java/org/apache/iotdb/exception/IoTDBSessionException.java diff --git a/session/src/main/java/org/apache/iotdb/session/Session.java b/session/src/main/java/org/apache/iotdb/session/Session.java new file mode 100644 index 00000000000..f56538ad20b --- /dev/null +++ b/session/src/main/java/org/apache/iotdb/session/Session.java @@ -0,0 +1,189 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.iotdb.session; + +import java.time.ZoneId; +import org.apache.iotdb.exception.IoTDBSessionException; +import org.apache.iotdb.jdbc.Config; +import org.apache.iotdb.jdbc.IoTDBConnection; +import org.apache.iotdb.jdbc.IoTDBSQLException; +import org.apache.iotdb.jdbc.Utils; +import org.apache.iotdb.service.rpc.thrift.TSBatchInsertionReq; +import org.apache.iotdb.service.rpc.thrift.TSCloseSessionReq; +import org.apache.iotdb.service.rpc.thrift.TSExecuteBatchStatementResp; +import org.apache.iotdb.service.rpc.thrift.TSGetTimeZoneResp; +import org.apache.iotdb.service.rpc.thrift.TSIService; +import org.apache.iotdb.service.rpc.thrift.TSOpenSessionReq; +import org.apache.iotdb.service.rpc.thrift.TSOpenSessionResp; +import org.apache.iotdb.service.rpc.thrift.TSProtocolVersion; +import org.apache.iotdb.service.rpc.thrift.TSSetTimeZoneReq; +import org.apache.iotdb.service.rpc.thrift.TSSetTimeZoneResp; +import org.apache.iotdb.service.rpc.thrift.TS_SessionHandle; +import org.apache.iotdb.tsfile.write.record.RowBatch; +import org.apache.iotdb.tsfile.write.schema.MeasurementSchema; +import org.apache.thrift.TException; +import org.apache.thrift.protocol.TBinaryProtocol; +import org.apache.thrift.protocol.TCompactProtocol; +import org.apache.thrift.transport.TSocket; +import org.apache.thrift.transport.TTransportException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Session { + + private static final Logger logger = LoggerFactory.getLogger(Session.class); + private String host; + private int port; + private String username; + private String password; + private final TSProtocolVersion protocolVersion = TSProtocolVersion.IOTDB_SERVICE_PROTOCOL_V1; + public TSIService.Iface client = null; + private TS_SessionHandle sessionHandle = null; + private TSocket transport; + private boolean isClosed = true; + private ZoneId zoneId; + + public Session(String host, int port) { + this(host, port, Config.DEFAULT_USER, Config.DEFALUT_PASSWORD); + } + + public Session(String host, String port, String username, String password) { + this(host, Integer.parseInt(port), username, password); + } + + public Session(String host, int port, String username, String password) { + this.host = host; + this.port = port; + this.username = username; + this.password = password; + } + + public void open() { + open(false, 0); + } + + public void open(boolean enableRPCCompression, int connectionTimeoutInMs) { + transport = new TSocket(host, port, connectionTimeoutInMs); + if (!transport.isOpen()) { + try { + transport.open(); + } catch (TTransportException e) { + throw new IoTDBSessionException(e); + } + } + + if(enableRPCCompression) { + client = new TSIService.Client(new TCompactProtocol(transport)); + } + else { + client = new TSIService.Client(new TBinaryProtocol(transport)); + } + + TSOpenSessionReq openReq = new TSOpenSessionReq(TSProtocolVersion.IOTDB_SERVICE_PROTOCOL_V1); + openReq.setUsername(username); + openReq.setPassword(password); + + try { + TSOpenSessionResp openResp = client.openSession(openReq); + + // validate connection + try { + Utils.verifySuccess(openResp.getStatus()); + } catch (IoTDBSQLException e) { + transport.close(); + throw e; + } + + if (protocolVersion.getValue() != openResp.getServerProtocolVersion().getValue()) { + throw new TException(String + .format("Protocol not supported, Client version is {}, but Server version is {}", + protocolVersion.getValue(), openResp.getServerProtocolVersion().getValue())); + } + + sessionHandle = openResp.getSessionHandle(); + + if (zoneId != null) { + setTimeZone(zoneId.toString()); + } else { + zoneId = ZoneId.of(getTimeZone()); + } + + } catch (TException | IoTDBSQLException e) { + throw new IoTDBSessionException(String.format("Can not open session to %s:%s with user: %s.", + host, port, username), e); + } + isClosed = false; + + client = IoTDBConnection.newSynchronizedClient(client); + + } + + public void close() { + if (isClosed) { + return; + } + TSCloseSessionReq req = new TSCloseSessionReq(sessionHandle); + try { + client.closeSession(req); + } catch (TException e) { + throw new IoTDBSessionException("Error occurs when closing session at server. Maybe server is down.", e); + } finally { + isClosed = true; + if (transport != null) { + transport.close(); + } + } + } + + public TSExecuteBatchStatementResp insertBatch(RowBatch rowBatch) { + TSBatchInsertionReq request = new TSBatchInsertionReq(); + request.deviceId = rowBatch.deviceId; + for (MeasurementSchema measurementSchema: rowBatch.measurements) { + request.addToMeasurements(measurementSchema.getMeasurementId()); + request.addToTypes(measurementSchema.getType().ordinal()); + } + request.setTimestamps(Utils.getTimeBuffer(rowBatch)); + request.setValues(Utils.getValueBuffer(rowBatch)); + request.setSize(rowBatch.batchSize); + + try { + return client.insertBatch(request); + } catch (TException e) { + throw new IoTDBSessionException(e); + } + } + + public String getTimeZone() throws TException, IoTDBSQLException { + if (zoneId != null) { + return zoneId.toString(); + } + + TSGetTimeZoneResp resp = client.getTimeZone(); + Utils.verifySuccess(resp.getStatus()); + return resp.getTimeZone(); + } + + public void setTimeZone(String zoneId) throws TException, IoTDBSQLException { + TSSetTimeZoneReq req = new TSSetTimeZoneReq(zoneId); + TSSetTimeZoneResp resp = client.setTimeZone(req); + Utils.verifySuccess(resp.getStatus()); + this.zoneId = ZoneId.of(zoneId); + } + +}