• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

apache / iotdb / #10006

06 Sep 2023 05:15AM CUT coverage: 47.697% (+0.006%) from 47.691%
#10006

push

travis_ci

web-flow
[RatisConsensus] retry cache expiration time should be longer than retriable-client wait duration (#11045) (#11052)

13 of 13 new or added lines in 1 file covered. (100.0%)

80213 of 168172 relevant lines covered (47.7%)

0.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements.  See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership.  The ASF licenses this file
6
 * to you under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in compliance
8
 * with the License.  You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19

20
package org.apache.iotdb.cli;
21

22
import org.apache.iotdb.cli.utils.IoTPrinter;
23
import org.apache.iotdb.exception.ArgsErrorException;
24
import org.apache.iotdb.jdbc.IoTDBConnection;
25
import org.apache.iotdb.jdbc.IoTDBJDBCResultSet;
26
import org.apache.iotdb.rpc.IoTDBConnectionException;
27
import org.apache.iotdb.rpc.RpcUtils;
28
import org.apache.iotdb.service.rpc.thrift.ServerProperties;
29
import org.apache.iotdb.tool.ImportCsv;
30

31
import org.apache.commons.cli.CommandLine;
32
import org.apache.commons.cli.Option;
33
import org.apache.commons.cli.Options;
34
import org.apache.commons.lang3.ArrayUtils;
35

36
import java.io.BufferedReader;
37
import java.io.IOException;
38
import java.io.InputStreamReader;
39
import java.sql.ResultSet;
40
import java.sql.ResultSetMetaData;
41
import java.sql.SQLException;
42
import java.sql.Statement;
43
import java.time.ZoneId;
44
import java.util.ArrayList;
45
import java.util.Arrays;
46
import java.util.HashSet;
47
import java.util.List;
48
import java.util.Set;
49

50
import static org.apache.iotdb.cli.utils.IoTPrinter.computeHANCount;
51
import static org.apache.iotdb.cli.utils.IoTPrinter.printBlockLine;
52
import static org.apache.iotdb.cli.utils.IoTPrinter.printCount;
53
import static org.apache.iotdb.cli.utils.IoTPrinter.printRow;
54
import static org.apache.iotdb.cli.utils.IoTPrinter.println;
55

56
public abstract class AbstractCli {
×
57

58
  static final String HOST_ARGS = "h";
59
  static final String HOST_NAME = "host";
60

61
  static final String HELP_ARGS = "help";
62

63
  static final String PORT_ARGS = "p";
64
  static final String PORT_NAME = "port";
65

66
  static final String PW_ARGS = "pw";
67
  private static final String PW_NAME = "password";
68

69
  static final String USERNAME_ARGS = "u";
70
  static final String USERNAME_NAME = "username";
71

72
  private static final String EXECUTE_ARGS = "e";
73
  private static final String EXECUTE_NAME = "execute";
74
  private static final String NULL = "null";
75

76
  static final int CODE_OK = 0;
77
  static final int CODE_ERROR = 1;
78

79
  static final String ISO8601_ARGS = "disableISO8601";
80
  static final List<String> AGGREGRATE_TIME_LIST = new ArrayList<>();
×
81
  static final String MAX_PRINT_ROW_COUNT_ARGS = "maxPRC";
82
  private static final String MAX_PRINT_ROW_COUNT_NAME = "maxPrintRowCount";
83
  static final String RPC_COMPRESS_ARGS = "c";
84
  private static final String RPC_COMPRESS_NAME = "rpcCompressed";
85
  static final String TIMEOUT_ARGS = "timeout";
86
  private static final String TIMEOUT_NAME = "queryTimeout";
87
  static final String SET_MAX_DISPLAY_NUM = "set max_display_num";
88
  static final String SET_TIMESTAMP_DISPLAY = "set time_display_type";
89
  static final String SHOW_TIMESTAMP_DISPLAY = "show time_display_type";
90
  static final String SET_TIME_ZONE = "set time_zone";
91
  static final String SHOW_TIMEZONE = "show time_zone";
92
  static final String SET_FETCH_SIZE = "set fetch_size";
93
  static final String SHOW_FETCH_SIZE = "show fetch_size";
94
  private static final String HELP = "help";
95
  static final String IOTDB_CLI_PREFIX = "IoTDB";
96
  static final String SCRIPT_HINT = "./start-cli.sh(start-cli.bat if Windows)";
97
  static final String QUIT_COMMAND = "quit";
98
  static final String EXIT_COMMAND = "exit";
99
  private static final String SHOW_METADATA_COMMAND = "show timeseries";
100
  static final int MAX_HELP_CONSOLE_WIDTH = 88;
101
  static final String TIMESTAMP_STR = "Time";
102
  private static final String IMPORT_CMD = "import";
103
  static int maxPrintRowCount = 1000;
×
104
  private static int fetchSize = 1000;
×
105
  static int queryTimeout = 0;
×
106
  static String timestampPrecision = "ms";
×
107
  static String timeFormat = RpcUtils.DEFAULT_TIME_FORMAT;
×
108
  private static boolean continuePrint = false;
×
109

110
  private static int lineCount = 0;
×
111
  private static final String SUCCESS_MESSAGE = "The statement is executed successfully.";
112

113
  private static boolean isReachEnd = false;
×
114

115
  static String host = "127.0.0.1";
×
116
  static String port = "6667";
×
117
  static String username;
118
  static String password;
119
  static String execute;
120
  static boolean hasExecuteSQL = false;
×
121

122
  static Set<String> keywordSet = new HashSet<>();
×
123

124
  static ServerProperties properties = null;
×
125

126
  private static boolean cursorBeforeFirst = true;
×
127

128
  static int lastProcessStatus = CODE_OK;
×
129

130
  static void init() {
131
    keywordSet.add("-" + HOST_ARGS);
×
132
    keywordSet.add("-" + HELP_ARGS);
×
133
    keywordSet.add("-" + PORT_ARGS);
×
134
    keywordSet.add("-" + PW_ARGS);
×
135
    keywordSet.add("-" + USERNAME_ARGS);
×
136
    keywordSet.add("-" + EXECUTE_ARGS);
×
137
    keywordSet.add("-" + ISO8601_ARGS);
×
138
    keywordSet.add("-" + MAX_PRINT_ROW_COUNT_ARGS);
×
139
    keywordSet.add("-" + RPC_COMPRESS_ARGS);
×
140
  }
×
141

142
  static Options createOptions() {
143
    Options options = new Options();
×
144
    Option help = new Option(HELP_ARGS, false, "Display help information(optional)");
×
145
    help.setRequired(false);
×
146
    options.addOption(help);
×
147

148
    Option timeFormat = new Option(ISO8601_ARGS, false, "Display timestamp in number(optional)");
×
149
    timeFormat.setRequired(false);
×
150
    options.addOption(timeFormat);
×
151

152
    Option host =
×
153
        Option.builder(HOST_ARGS)
×
154
            .argName(HOST_NAME)
×
155
            .hasArg()
×
156
            .desc("Host Name (optional, default 127.0.0.1)")
×
157
            .build();
×
158
    options.addOption(host);
×
159

160
    Option port =
×
161
        Option.builder(PORT_ARGS)
×
162
            .argName(PORT_NAME)
×
163
            .hasArg()
×
164
            .desc("Port (optional, default 6667)")
×
165
            .build();
×
166
    options.addOption(port);
×
167

168
    Option username =
×
169
        Option.builder(USERNAME_ARGS)
×
170
            .argName(USERNAME_NAME)
×
171
            .hasArg()
×
172
            .desc("User name (required)")
×
173
            .required()
×
174
            .build();
×
175
    options.addOption(username);
×
176

177
    Option password =
×
178
        Option.builder(PW_ARGS).argName(PW_NAME).hasArg().desc("password (optional)").build();
×
179
    options.addOption(password);
×
180

181
    Option execute =
×
182
        Option.builder(EXECUTE_ARGS)
×
183
            .argName(EXECUTE_NAME)
×
184
            .hasArg()
×
185
            .desc("execute statement (optional)")
×
186
            .build();
×
187
    options.addOption(execute);
×
188

189
    Option maxPrintCount =
×
190
        Option.builder(MAX_PRINT_ROW_COUNT_ARGS)
×
191
            .argName(MAX_PRINT_ROW_COUNT_NAME)
×
192
            .hasArg()
×
193
            .desc("Maximum number of rows displayed (optional)")
×
194
            .build();
×
195
    options.addOption(maxPrintCount);
×
196

197
    Option isRpcCompressed =
×
198
        Option.builder(RPC_COMPRESS_ARGS)
×
199
            .argName(RPC_COMPRESS_NAME)
×
200
            .desc("Rpc Compression enabled or not")
×
201
            .build();
×
202
    options.addOption(isRpcCompressed);
×
203

204
    Option queryTimeout =
×
205
        Option.builder(TIMEOUT_ARGS)
×
206
            .argName(TIMEOUT_NAME)
×
207
            .hasArg()
×
208
            .desc(
×
209
                "The timeout in second. "
210
                    + "Using the configuration of server if it's not set (optional)")
211
            .build();
×
212
    options.addOption(queryTimeout);
×
213
    return options;
×
214
  }
215

216
  static String checkRequiredArg(
217
      String arg, String name, CommandLine commandLine, boolean isRequired, String defaultValue)
218
      throws ArgsErrorException {
219
    String str = commandLine.getOptionValue(arg);
×
220
    if (str == null) {
×
221
      if (isRequired) {
×
222
        String msg =
×
223
            String.format(
×
224
                "%s: Required values for option '%s' not provided", IOTDB_CLI_PREFIX, name);
225
        println(msg);
×
226
        println("Use -help for more information");
×
227
        throw new ArgsErrorException(msg);
×
228
      } else if (defaultValue == null) {
×
229
        String msg =
×
230
            String.format("%s: Required values for option '%s' is null.", IOTDB_CLI_PREFIX, name);
×
231
        throw new ArgsErrorException(msg);
×
232
      } else {
233
        return defaultValue;
×
234
      }
235
    }
236
    return str;
×
237
  }
238

239
  private static void setFetchSize(String fetchSizeString) {
240
    long tmp = Long.parseLong(fetchSizeString.trim());
×
241
    if (tmp > Integer.MAX_VALUE || tmp < 0) {
×
242
      fetchSize = Integer.MAX_VALUE;
×
243
    } else {
244
      fetchSize = Integer.parseInt(fetchSizeString.trim());
×
245
    }
246
  }
×
247

248
  private static int setFetchSize(String specialCmd, String cmd) {
249
    String[] values = specialCmd.split("=");
×
250
    if (values.length != 2) {
×
251
      println(String.format("Fetch size format error, please input like %s=10000", SET_FETCH_SIZE));
×
252
      return CODE_ERROR;
×
253
    }
254
    try {
255
      setFetchSize(cmd.split("=")[1]);
×
256
    } catch (Exception e) {
×
257
      println(String.format("Fetch size format error, %s", e.getMessage()));
×
258
      return CODE_ERROR;
×
259
    }
×
260
    println("Fetch size has set to " + values[1].trim());
×
261
    return CODE_OK;
×
262
  }
263

264
  static void setMaxDisplayNumber(String maxDisplayNum) {
265
    long tmp = Long.parseLong(maxDisplayNum.trim());
×
266
    if (tmp > Integer.MAX_VALUE) {
×
267
      throw new NumberFormatException();
×
268
    } else if (tmp <= 0) {
×
269
      continuePrint = true;
×
270
    } else {
271
      maxPrintRowCount = Integer.parseInt(maxDisplayNum.trim());
×
272
    }
273
  }
×
274

275
  static void setQueryTimeout(String timeoutString) {
276
    long timeout = Long.parseLong(timeoutString.trim());
×
277
    if (timeout > Integer.MAX_VALUE || timeout < 0) {
×
278
      queryTimeout = 0;
×
279
    } else {
280
      queryTimeout = Integer.parseInt(timeoutString.trim());
×
281
    }
282
  }
×
283

284
  static String[] removePasswordArgs(String[] args) {
285
    int index = -1;
×
286
    for (int i = 0; i < args.length; i++) {
×
287
      if (args[i].equals("-" + PW_ARGS)) {
×
288
        index = i;
×
289
        break;
×
290
      }
291
    }
292
    if (index >= 0
×
293
        && ((index + 1 >= args.length)
294
            || (index + 1 < args.length && keywordSet.contains(args[index + 1])))) {
×
295
      return ArrayUtils.remove(args, index);
×
296
    }
297
    return args;
×
298
  }
299

300
  @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
301
  static String[] processExecuteArgs(String[] args) {
302
    int index = -1;
×
303
    for (int i = 0; i < args.length; i++) {
×
304
      if (args[i].equals("-" + EXECUTE_ARGS)) {
×
305
        index = i;
×
306
        break;
×
307
      }
308
    }
309
    if (index >= 0
×
310
        && ((index + 1 >= args.length)
311
            || (index + 1 < args.length && keywordSet.contains(args[index + 1])))) {
×
312
      return ArrayUtils.remove(args, index);
×
313
    } else if (index == -1) {
×
314
      return args;
×
315
    } else {
316
      StringBuilder executeCommand = new StringBuilder();
×
317
      for (int j = index + 1; j < args.length; j++) {
×
318
        executeCommand.append(args[j]).append(" ");
×
319
      }
320
      // remove last space
321
      executeCommand.deleteCharAt(executeCommand.length() - 1);
×
322
      // some bashes may not remove quotes of parameters automatically, remove them in that case
323
      if (executeCommand.charAt(0) == '\'' || executeCommand.charAt(0) == '\"') {
×
324
        executeCommand.deleteCharAt(0);
×
325
        if (executeCommand.charAt(executeCommand.length() - 1) == '\''
×
326
            || executeCommand.charAt(executeCommand.length() - 1) == '\"') {
×
327
          executeCommand.deleteCharAt(executeCommand.length() - 1);
×
328
        }
329
      }
330

331
      execute = executeCommand.toString();
×
332
      hasExecuteSQL = true;
×
333
      // When execute sql in CLI with -e mode, we should print all results by setting continuePrint
334
      // is true.
335
      continuePrint = true;
×
336
      args = Arrays.copyOfRange(args, 0, index);
×
337
      return args;
×
338
    }
339
  }
340

341
  static void displayLogo(String logo, String version, String buildInfo) {
342
    println(
×
343
        (logo != null
×
344
                ? logo
×
345
                : (" _____       _________  ______   ______    \n"
×
346
                    + "|_   _|     |  _   _  ||_   _ `.|_   _ \\   \n"
347
                    + "  | |   .--.|_/ | | \\_|  | | `. \\ | |_) |  \n"
348
                    + "  | | / .'`\\ \\  | |      | |  | | |  __'.  \n"
349
                    + " _| |_| \\__. | _| |_    _| |_.' /_| |__) | \n"
350
                    + "|_____|'.__.' |_____|  |______.'|_______/  "))
351
            + "version "
352
            + version
353
            + " (Build: "
354
            + (buildInfo != null ? buildInfo : "UNKNOWN")
×
355
            + ")"
356
            + "\n"
357
            + "                                           \n");
358
  }
×
359

360
  static void echoStarting() {
361
    println("---------------------");
×
362
    println("Starting IoTDB Cli");
×
363
    println("---------------------");
×
364
  }
×
365

366
  static OperationResult handleInputCmd(String cmd, IoTDBConnection connection) {
367
    lastProcessStatus = CODE_OK;
×
368
    String specialCmd = cmd.toLowerCase().trim();
×
369

370
    if (QUIT_COMMAND.equals(specialCmd) || EXIT_COMMAND.equals(specialCmd)) {
×
371
      return OperationResult.STOP_OPER;
×
372
    }
373
    if (HELP.equals(specialCmd)) {
×
374
      showHelp();
×
375
      return OperationResult.CONTINUE_OPER;
×
376
    }
377
    if (specialCmd.startsWith(SET_TIMESTAMP_DISPLAY)) {
×
378
      lastProcessStatus = setTimestampDisplay(specialCmd, cmd);
×
379
      return OperationResult.CONTINUE_OPER;
×
380
    }
381

382
    if (specialCmd.startsWith(SET_TIME_ZONE)) {
×
383
      lastProcessStatus = setTimeZone(specialCmd, cmd, connection);
×
384
      return OperationResult.CONTINUE_OPER;
×
385
    }
386

387
    if (specialCmd.startsWith(SET_FETCH_SIZE)) {
×
388
      lastProcessStatus = setFetchSize(specialCmd, cmd);
×
389
      return OperationResult.CONTINUE_OPER;
×
390
    }
391

392
    if (specialCmd.startsWith(SET_MAX_DISPLAY_NUM)) {
×
393
      lastProcessStatus = setMaxDisplayNum(specialCmd, cmd);
×
394
      return OperationResult.CONTINUE_OPER;
×
395
    }
396

397
    if (specialCmd.startsWith(SHOW_TIMEZONE)) {
×
398
      lastProcessStatus = showTimeZone(connection);
×
399
      return OperationResult.CONTINUE_OPER;
×
400
    }
401
    if (specialCmd.startsWith(SHOW_TIMESTAMP_DISPLAY)) {
×
402
      println("Current time format: " + timeFormat);
×
403
      return OperationResult.CONTINUE_OPER;
×
404
    }
405
    if (specialCmd.startsWith(SHOW_FETCH_SIZE)) {
×
406
      println("Current fetch size: " + fetchSize);
×
407
      return OperationResult.CONTINUE_OPER;
×
408
    }
409

410
    if (specialCmd.startsWith(IMPORT_CMD)) {
×
411
      lastProcessStatus = importCmd(specialCmd, cmd, connection);
×
412
      return OperationResult.CONTINUE_OPER;
×
413
    }
414

415
    lastProcessStatus = executeQuery(connection, cmd);
×
416
    return OperationResult.NO_OPER;
×
417
  }
418

419
  private static void showHelp() {
420
    println("    <your-sql>\t\t\t execute your sql statment");
×
421
    println(
×
422
        String.format("    %s\t\t show how many timeseries are in iotdb", SHOW_METADATA_COMMAND));
×
423
    println(
×
424
        String.format(
×
425
            "    %s=xxx\t eg. long, default, ISO8601, yyyy-MM-dd HH:mm:ss.",
426
            SET_TIMESTAMP_DISPLAY));
427
    println(String.format("    %s\t show time display type", SHOW_TIMESTAMP_DISPLAY));
×
428
    println(String.format("    %s=xxx\t\t eg. +08:00, Asia/Shanghai.", SET_TIME_ZONE));
×
429
    println(String.format("    %s\t\t show cli time zone", SHOW_TIMEZONE));
×
430
    println(
×
431
        String.format(
×
432
            "    %s=xxx\t\t set fetch size when querying data from server.", SET_FETCH_SIZE));
433
    println(String.format("    %s\t\t show fetch size", SHOW_FETCH_SIZE));
×
434
    println(
×
435
        String.format(
×
436
            "    %s=xxx\t eg. set max lines for cli to ouput, -1 equals to unlimited.",
437
            SET_MAX_DISPLAY_NUM));
438
  }
×
439

440
  private static int setTimestampDisplay(String specialCmd, String cmd) {
441
    String[] values = specialCmd.split("=");
×
442
    if (values.length != 2) {
×
443
      println(
×
444
          String.format(
×
445
              "Time display format error, please input like %s=ISO8601", SET_TIMESTAMP_DISPLAY));
446
      return CODE_ERROR;
×
447
    }
448
    try {
449
      timeFormat = RpcUtils.setTimeFormat(cmd.split("=")[1]);
×
450
    } catch (Exception e) {
×
451
      println(String.format("time display format error, %s", e.getMessage()));
×
452
      return CODE_ERROR;
×
453
    }
×
454
    println("Time display type has set to " + cmd.split("=")[1].trim());
×
455
    return CODE_OK;
×
456
  }
457

458
  /**
459
   * if cli has not specified a zoneId, it will be set to cli's system timezone by default otherwise
460
   * for insert and query accuracy cli should set timezone the same for all sessions.
461
   *
462
   * @param specialCmd
463
   * @param cmd
464
   * @param connection
465
   * @return execute result code
466
   */
467
  private static int setTimeZone(String specialCmd, String cmd, IoTDBConnection connection) {
468
    String[] values = specialCmd.split("=");
×
469
    if (values.length != 2) {
×
470
      println(String.format("Time zone format error, please input like %s=+08:00", SET_TIME_ZONE));
×
471
      return CODE_ERROR;
×
472
    }
473
    try {
474
      connection.setTimeZone(cmd.split("=")[1].trim());
×
475
    } catch (Exception e) {
×
476
      println(String.format("Time zone format error: %s", e.getMessage()));
×
477
      return CODE_ERROR;
×
478
    }
×
479
    println("Time zone has set to " + values[1].trim());
×
480
    return CODE_OK;
×
481
  }
482

483
  private static int setMaxDisplayNum(String specialCmd, String cmd) {
484
    String[] values = specialCmd.split("=");
×
485
    if (values.length != 2) {
×
486
      println(
×
487
          String.format(
×
488
              "Max display number format error, please input like %s = 10000",
489
              SET_MAX_DISPLAY_NUM));
490
      return CODE_ERROR;
×
491
    }
492
    try {
493
      setMaxDisplayNumber(cmd.split("=")[1]);
×
494
    } catch (Exception e) {
×
495
      println(String.format("Max display number format error, %s", e.getMessage()));
×
496
      return CODE_ERROR;
×
497
    }
×
498
    println("Max display number has set to " + values[1].trim());
×
499
    return CODE_OK;
×
500
  }
501

502
  private static int showTimeZone(IoTDBConnection connection) {
503
    try {
504
      println("Current time zone: " + connection.getTimeZone());
×
505
    } catch (Exception e) {
×
506
      println("Cannot get time zone from server side because: " + e.getMessage());
×
507
      return CODE_ERROR;
×
508
    }
×
509
    return CODE_OK;
×
510
  }
511

512
  private static int importCmd(String specialCmd, String cmd, IoTDBConnection connection) {
513
    String[] values = specialCmd.split(" ");
×
514
    if (values.length != 2) {
×
515
      println(
×
516
          "Please input like: import /User/myfile. "
517
              + "Noted that your file path cannot contain any space character)");
518
      return CODE_ERROR;
×
519
    }
520
    println(cmd.split(" ")[1]);
×
521
    try {
522
      return ImportCsv.importFromTargetPath(
×
523
          host,
524
          Integer.parseInt(port),
×
525
          username,
526
          password,
527
          cmd.split(" ")[1],
×
528
          connection.getTimeZone());
×
529
    } catch (IoTDBConnectionException e) {
×
530
      IoTPrinter.printException(e);
×
531
      return CODE_ERROR;
×
532
    }
533
  }
534

535
  @SuppressWarnings({"squid:S3776"}) // Suppress high Cognitive Complexity warning
536
  private static int executeQuery(IoTDBConnection connection, String cmd) {
537
    int executeStatus = CODE_OK;
×
538
    long startTime = System.currentTimeMillis();
×
539
    try (Statement statement = connection.createStatement()) {
×
540
      ZoneId zoneId = ZoneId.of(connection.getTimeZone());
×
541
      statement.setFetchSize(fetchSize);
×
542
      boolean hasResultSet = statement.execute(cmd.trim());
×
543
      if (hasResultSet) {
×
544
        // print the result
545
        try (ResultSet resultSet = statement.getResultSet()) {
×
546
          ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
×
547
          int columnLength = resultSetMetaData.getColumnCount();
×
548
          List<Integer> maxSizeList = new ArrayList<>(columnLength);
×
549
          List<List<String>> lists =
×
550
              cacheResult(resultSet, maxSizeList, columnLength, resultSetMetaData, zoneId);
×
551
          output(lists, maxSizeList);
×
552
          long costTime = System.currentTimeMillis() - startTime;
×
553
          println(String.format("It costs %.3fs", costTime / 1000.0));
×
554
          while (!isReachEnd) {
×
555
            if (continuePrint) {
×
556
              maxSizeList = new ArrayList<>(columnLength);
×
557
              lists = cacheResult(resultSet, maxSizeList, columnLength, resultSetMetaData, zoneId);
×
558
              output(lists, maxSizeList);
×
559
              continue;
×
560
            }
561
            println(
×
562
                String.format(
×
563
                    "Reach the max_display_num = %s. Press ENTER to show more, input 'q' to quit.",
564
                    maxPrintRowCount));
×
565
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
×
566
            try {
567
              if ("".equals(br.readLine())) {
×
568
                maxSizeList = new ArrayList<>(columnLength);
×
569
                lists =
×
570
                    cacheResult(resultSet, maxSizeList, columnLength, resultSetMetaData, zoneId);
×
571
                output(lists, maxSizeList);
×
572
              } else {
573
                break;
×
574
              }
575
            } catch (IOException e) {
×
576
              IoTPrinter.printException(e);
×
577
              executeStatus = CODE_ERROR;
×
578
            }
×
579
          }
×
580
          // output tracing activity
581
          if (((IoTDBJDBCResultSet) resultSet).isSetTracingInfo()) {
×
582
            maxSizeList = new ArrayList<>(2);
×
583
            lists = cacheTracingInfo(resultSet, maxSizeList);
×
584
            outputTracingInfo(lists, maxSizeList);
×
585
          }
586
        }
587
      } else {
588
        println("Msg: " + SUCCESS_MESSAGE);
×
589
      }
590
    } catch (Exception e) {
×
591
      println("Msg: " + e.getMessage());
×
592
      executeStatus = CODE_ERROR;
×
593
    } finally {
594
      resetArgs();
×
595
    }
596
    return executeStatus;
×
597
  }
598

599
  /**
600
   * cache all results.
601
   *
602
   * @param resultSet jdbc resultSet
603
   * @param maxSizeList the longest result of every column
604
   * @param columnCount the number of column
605
   * @param resultSetMetaData jdbc resultSetMetaData
606
   * @param zoneId your time zone
607
   * @return {@literal List<List<String>> result}
608
   * @throws SQLException throw exception
609
   */
610
  @SuppressWarnings({"squid:S6541", "squid:S3776"}) // Suppress high Cognitive Complexity warning
611
  // Methods should not perform too many tasks (aka Brain method)
612
  private static List<List<String>> cacheResult(
613
      ResultSet resultSet,
614
      List<Integer> maxSizeList,
615
      int columnCount,
616
      ResultSetMetaData resultSetMetaData,
617
      ZoneId zoneId)
618
      throws SQLException {
619

620
    int j = 0;
×
621
    if (cursorBeforeFirst) {
×
622
      isReachEnd = !resultSet.next();
×
623
      cursorBeforeFirst = false;
×
624
    }
625

626
    List<List<String>> lists = new ArrayList<>(columnCount);
×
627
    int endTimeIndex = -1;
×
628
    if (resultSet instanceof IoTDBJDBCResultSet) {
×
629
      for (int i = 1; i <= columnCount; i++) {
×
630
        List<String> list = new ArrayList<>(maxPrintRowCount + 1);
×
631
        String columnLabel = resultSetMetaData.getColumnLabel(i);
×
632
        if (columnLabel.equalsIgnoreCase("__endTime")) {
×
633
          endTimeIndex = i;
×
634
        }
635
        list.add(columnLabel);
×
636
        lists.add(list);
×
637
        int count = computeHANCount(columnLabel);
×
638
        maxSizeList.add(columnLabel.length() + count);
×
639
      }
640

641
      boolean printTimestamp = !((IoTDBJDBCResultSet) resultSet).isIgnoreTimeStamp();
×
642
      while (j < maxPrintRowCount && !isReachEnd) {
×
643
        for (int i = 1; i <= columnCount; i++) {
×
644
          String tmp;
645
          if (printTimestamp && i == 1) {
×
646
            tmp =
×
647
                RpcUtils.formatDatetime(
×
648
                    timeFormat, timestampPrecision, resultSet.getLong(TIMESTAMP_STR), zoneId);
×
649
          } else if (endTimeIndex == i) {
×
650
            tmp =
×
651
                RpcUtils.formatDatetime(
×
652
                    timeFormat, timestampPrecision, resultSet.getLong(i), zoneId);
×
653
          } else {
654
            tmp = resultSet.getString(i);
×
655
          }
656
          if (tmp == null) {
×
657
            tmp = NULL;
×
658
          }
659
          lists.get(i - 1).add(tmp);
×
660
          int count = computeHANCount(tmp);
×
661
          int realLength = tmp.length() + count;
×
662
          if (maxSizeList.get(i - 1) < realLength) {
×
663
            maxSizeList.set(i - 1, realLength);
×
664
          }
665
        }
666
        j++;
×
667
        isReachEnd = !resultSet.next();
×
668
      }
669
      return lists;
×
670
    }
671

672
    for (int i = 1; i <= columnCount; i += 2) {
×
673
      List<String> timeList = new ArrayList<>(maxPrintRowCount + 1);
×
674
      timeList.add(resultSetMetaData.getColumnLabel(i).substring(0, TIMESTAMP_STR.length()));
×
675
      lists.add(timeList);
×
676
      List<String> valueList = new ArrayList<>(maxPrintRowCount + 1);
×
677
      valueList.add(resultSetMetaData.getColumnLabel(i + 1));
×
678
      lists.add(valueList);
×
679
      maxSizeList.add(TIMESTAMP_STR.length());
×
680
      maxSizeList.add(resultSetMetaData.getColumnLabel(i + 1).length());
×
681
    }
682

683
    while (j < maxPrintRowCount && !isReachEnd) {
×
684
      for (int i = 1; i <= columnCount; i++) {
×
685
        String tmp = resultSet.getString(i);
×
686
        if (tmp == null) {
×
687
          tmp = NULL;
×
688
        }
689
        if (i % 2 != 0 && !tmp.equals(NULL)) {
×
690
          tmp =
×
691
              RpcUtils.formatDatetime(timeFormat, timestampPrecision, Long.parseLong(tmp), zoneId);
×
692
        }
693
        lists.get(i - 1).add(tmp);
×
694
        if (maxSizeList.get(i - 1) < tmp.length()) {
×
695
          maxSizeList.set(i - 1, tmp.length());
×
696
        }
697
      }
698
      j++;
×
699
      isReachEnd = !resultSet.next();
×
700
    }
701
    return lists;
×
702
  }
703

704
  private static List<List<String>> cacheTracingInfo(ResultSet resultSet, List<Integer> maxSizeList)
705
      throws Exception {
706
    List<List<String>> lists = new ArrayList<>(2);
×
707
    lists.add(0, new ArrayList<>());
×
708
    lists.add(1, new ArrayList<>());
×
709

710
    String activityStr = "Activity";
×
711
    String elapsedTimeStr = "Elapsed Time";
×
712
    lists.get(0).add(activityStr);
×
713
    lists.get(1).add(elapsedTimeStr);
×
714
    maxSizeList.add(0, activityStr.length());
×
715
    maxSizeList.add(1, elapsedTimeStr.length());
×
716

717
    List<String> activityList = ((IoTDBJDBCResultSet) resultSet).getActivityList();
×
718
    List<Long> elapsedTimeList = ((IoTDBJDBCResultSet) resultSet).getElapsedTimeList();
×
719
    String[] statisticsInfoList = {
×
720
      "seriesPathNum", "seqFileNum", "unSeqFileNum", "seqChunkInfo", "unSeqChunkInfo", "pageNumInfo"
721
    };
722

723
    for (int i = 0; i < activityList.size(); i++) {
×
724

725
      if (i == activityList.size() - 1) {
×
726
        // cache Statistics
727
        for (String infoName : statisticsInfoList) {
×
728
          String info = ((IoTDBJDBCResultSet) resultSet).getStatisticsInfoByName(infoName);
×
729
          lists.get(0).add(info);
×
730
          lists.get(1).add("");
×
731
          if (info.length() > maxSizeList.get(0)) {
×
732
            maxSizeList.set(0, info.length());
×
733
          }
734
        }
735
      }
736

737
      String activity = activityList.get(i);
×
738
      String elapsedTime = elapsedTimeList.get(i).toString();
×
739
      if (activity.length() > maxSizeList.get(0)) {
×
740
        maxSizeList.set(0, activity.length());
×
741
      }
742
      if (elapsedTime.length() > maxSizeList.get(1)) {
×
743
        maxSizeList.set(1, elapsedTime.length());
×
744
      }
745
      lists.get(0).add(activity);
×
746
      lists.get(1).add(elapsedTime);
×
747
    }
748

749
    return lists;
×
750
  }
751

752
  private static void output(List<List<String>> lists, List<Integer> maxSizeList) {
753
    printBlockLine(maxSizeList);
×
754
    printRow(lists, 0, maxSizeList);
×
755
    printBlockLine(maxSizeList);
×
756
    for (int i = 1; i < lists.get(0).size(); i++) {
×
757
      printRow(lists, i, maxSizeList);
×
758
    }
759
    printBlockLine(maxSizeList);
×
760
    if (isReachEnd) {
×
761
      lineCount += lists.get(0).size() - 1;
×
762
      printCount(lineCount);
×
763
    } else {
764
      lineCount += maxPrintRowCount;
×
765
    }
766
  }
×
767

768
  private static void outputTracingInfo(List<List<String>> lists, List<Integer> maxSizeList) {
769
    println();
×
770
    println("Tracing Activties:");
×
771
    printBlockLine(maxSizeList);
×
772
    printRow(lists, 0, maxSizeList);
×
773
    printBlockLine(maxSizeList);
×
774
    for (int i = 1; i < lists.get(0).size(); i++) {
×
775
      printRow(lists, i, maxSizeList);
×
776
    }
777
    printBlockLine(maxSizeList);
×
778
  }
×
779

780
  private static void resetArgs() {
781
    lineCount = 0;
×
782
    cursorBeforeFirst = true;
×
783
    isReachEnd = false;
×
784
  }
×
785

786
  enum OperationResult {
×
787
    STOP_OPER,
×
788
    CONTINUE_OPER,
×
789
    NO_OPER
×
790
  }
791

792
  static boolean processCommand(String s, IoTDBConnection connection) {
793
    if (s == null) {
×
794
      return true;
×
795
    }
796
    String[] cmds = s.trim().split(";");
×
797
    for (String cmd : cmds) {
×
798
      if (cmd != null && !"".equals(cmd.trim())) {
×
799
        OperationResult result = handleInputCmd(cmd, connection);
×
800
        switch (result) {
×
801
          case STOP_OPER:
802
            return false;
×
803
          case CONTINUE_OPER:
804
            continue;
×
805
          default:
806
            break;
807
        }
808
      }
809
    }
810
    return true;
×
811
  }
812
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc