You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ha...@apache.org on 2021/01/06 13:11:27 UTC

[iotdb] branch master updated: [ISSUE-2351] fix the case that column length is not right in CLI when the value contains Chinese characters (#2427)

This is an automated email from the ASF dual-hosted git repository.

haonan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new e2014e3  [ISSUE-2351] fix the case that column length is not right in CLI when the value contains Chinese characters (#2427)
e2014e3 is described below

commit e2014e384c7689097fb40956fdf7332c054495ee
Author: Al Wei <10...@qq.com>
AuthorDate: Wed Jan 6 21:11:07 2021 +0800

    [ISSUE-2351] fix the case that column length is not right in CLI when the value contains Chinese characters (#2427)
    
    * [FIX] fix the case that column length is not right in CLI when the value contains Chinese characters
    
    Co-authored-by: Al Wei <wz...@163.com>
---
 .../java/org/apache/iotdb/cli/AbstractCli.java     | 138 ++++++++-------------
 cli/src/main/java/org/apache/iotdb/cli/Cli.java    |   2 +
 cli/src/main/java/org/apache/iotdb/cli/WinCli.java |   3 +
 .../org/apache/iotdb/cli/utils/IoTPrinter.java     | 107 ++++++++++++++++
 4 files changed, 164 insertions(+), 86 deletions(-)

diff --git a/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java b/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java
index 61429d6..dab4744 100644
--- a/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java
+++ b/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java
@@ -18,10 +18,15 @@
  */
 package org.apache.iotdb.cli;
 
+import static org.apache.iotdb.cli.utils.IoTPrinter.computeHANCount;
+import static org.apache.iotdb.cli.utils.IoTPrinter.printBlockLine;
+import static org.apache.iotdb.cli.utils.IoTPrinter.printCount;
+import static org.apache.iotdb.cli.utils.IoTPrinter.printRow;
+import static org.apache.iotdb.cli.utils.IoTPrinter.println;
+
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.io.PrintStream;
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
@@ -36,7 +41,6 @@ import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.iotdb.exception.ArgsErrorException;
 import org.apache.iotdb.jdbc.IoTDBConnection;
 import org.apache.iotdb.jdbc.IoTDBJDBCResultSet;
@@ -107,7 +111,6 @@ public abstract class AbstractCli {
 
   static ServerProperties properties = null;
 
-  private static final PrintStream SCREEN_PRINTER = new PrintStream(System.out);
   private static boolean cursorBeforeFirst = true;
 
   static void init() {
@@ -122,16 +125,6 @@ public abstract class AbstractCli {
     keywordSet.add("-" + RPC_COMPRESS_ARGS);
   }
 
-
-
-  private static void printCount(int cnt) {
-    if (cnt == 0) {
-      println("Empty set.");
-    } else {
-      println("Total line number = " + cnt);
-    }
-  }
-
   static Options createOptions() {
     Options options = new Options();
     Option help = new Option(HELP_ARGS, false, "Display help information(optional)");
@@ -507,32 +500,24 @@ public abstract class AbstractCli {
   @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
   private static List<List<String>> cacheResult(ResultSet resultSet, List<Integer> maxSizeList,
       int columnCount, ResultSetMetaData resultSetMetaData, ZoneId zoneId) throws SQLException {
-    List<List<String>> lists = new ArrayList<>(columnCount);
-    if (resultSet instanceof IoTDBJDBCResultSet) {
-      for (int i = 1; i <= columnCount; i++) {
-        List<String> list = new ArrayList<>(maxPrintRowCount + 1);
-        list.add(resultSetMetaData.getColumnLabel(i));
-        lists.add(list);
-        maxSizeList.add(resultSetMetaData.getColumnLabel(i).length());
-      }
-    } else {
-      for (int i = 1; i <= columnCount; i += 2) {
-        List<String> timeList = new ArrayList<>(maxPrintRowCount + 1);
-        timeList.add(resultSetMetaData.getColumnLabel(i).substring(0, TIMESTAMP_STR.length()));
-        lists.add(timeList);
-        List<String> valueList = new ArrayList<>(maxPrintRowCount + 1);
-        valueList.add(resultSetMetaData.getColumnLabel(i + 1));
-        lists.add(valueList);
-        maxSizeList.add(TIMESTAMP_STR.length());
-        maxSizeList.add(resultSetMetaData.getColumnLabel(i + 1).length());
-      }
-    }
+
     int j = 0;
     if (cursorBeforeFirst) {
       isReachEnd = !resultSet.next();
       cursorBeforeFirst = false;
     }
+
+    List<List<String>> lists = new ArrayList<>(columnCount);
     if (resultSet instanceof IoTDBJDBCResultSet) {
+      for (int i = 1; i <= columnCount; i++) {
+        List<String> list = new ArrayList<>(maxPrintRowCount + 1);
+        String columnLabel = resultSetMetaData.getColumnLabel(i);
+        list.add(columnLabel);
+        lists.add(list);
+        int count = computeHANCount(columnLabel);
+        maxSizeList.add(columnLabel.length() + count);
+      }
+
       boolean printTimestamp = !((IoTDBJDBCResultSet) resultSet).isIgnoreTimeStamp();
       while (j < maxPrintRowCount && !isReachEnd) {
         for (int i = 1; i <= columnCount; i++) {
@@ -547,35 +532,49 @@ public abstract class AbstractCli {
             tmp = NULL;
           }
           lists.get(i - 1).add(tmp);
-          if (maxSizeList.get(i - 1) < tmp.length()) {
-            maxSizeList.set(i - 1, tmp.length());
+          int count = computeHANCount(tmp);
+          int realLength = tmp.length() + count;
+          if (maxSizeList.get(i - 1) < realLength) {
+            maxSizeList.set(i - 1, realLength);
           }
         }
         j++;
         isReachEnd = !resultSet.next();
       }
       return lists;
-    } else {
-      while (j < maxPrintRowCount && !isReachEnd) {
-        for (int i = 1; i <= columnCount; i++) {
-          String tmp = resultSet.getString(i);
-          if (tmp == null) {
-            tmp = NULL;
-          }
-          if (i % 2 != 0 && !tmp.equals(NULL)) {
-            tmp = RpcUtils.formatDatetime(timeFormat, timestampPrecision,
-                Long.parseLong(tmp), zoneId);
-          }
-          lists.get(i - 1).add(tmp);
-          if (maxSizeList.get(i - 1) < tmp.length()) {
-            maxSizeList.set(i - 1, tmp.length());
-          }
+    }
+
+    for (int i = 1; i <= columnCount; i += 2) {
+      List<String> timeList = new ArrayList<>(maxPrintRowCount + 1);
+      timeList.add(resultSetMetaData.getColumnLabel(i).substring(0, TIMESTAMP_STR.length()));
+      lists.add(timeList);
+      List<String> valueList = new ArrayList<>(maxPrintRowCount + 1);
+      valueList.add(resultSetMetaData.getColumnLabel(i + 1));
+      lists.add(valueList);
+      maxSizeList.add(TIMESTAMP_STR.length());
+      maxSizeList.add(resultSetMetaData.getColumnLabel(i + 1).length());
+    }
+
+    while (j < maxPrintRowCount && !isReachEnd) {
+      for (int i = 1; i <= columnCount; i++) {
+        String tmp = resultSet.getString(i);
+        if (tmp == null) {
+          tmp = NULL;
+        }
+        if (i % 2 != 0 && !tmp.equals(NULL)) {
+          tmp = RpcUtils.formatDatetime(timeFormat, timestampPrecision,
+              Long.parseLong(tmp), zoneId);
+        }
+        lists.get(i - 1).add(tmp);
+        if (maxSizeList.get(i - 1) < tmp.length()) {
+          maxSizeList.set(i - 1, tmp.length());
         }
-        j++;
-        isReachEnd = !resultSet.next();
       }
-      return lists;
+      j++;
+      isReachEnd = !resultSet.next();
     }
+    return lists;
+
   }
 
   private static void output(List<List<String>> lists, List<Integer> maxSizeList) {
@@ -600,43 +599,10 @@ public abstract class AbstractCli {
     isReachEnd = false;
   }
 
-  private static void printBlockLine(List<Integer> maxSizeList) {
-    StringBuilder blockLine = new StringBuilder();
-    for (Integer integer : maxSizeList) {
-      blockLine.append("+").append(StringUtils.repeat("-", integer));
-    }
-    blockLine.append("+");
-    println(blockLine.toString());
-  }
-
-  private static void printRow(List<List<String>> lists, int i, List<Integer> maxSizeList) {
-    printf("|");
-    for (int j = 0; j < maxSizeList.size(); j++) {
-      printf("%" + maxSizeList.get(j) + "s|", lists.get(j).get(i));
-    }
-    println();
-  }
-
   enum OperationResult {
     STOP_OPER, CONTINUE_OPER, NO_OPER
   }
 
-  private static void printf(String format, Object... args) {
-    SCREEN_PRINTER.printf(format, args);
-  }
-
-  static void print(String msg) {
-    SCREEN_PRINTER.print(msg);
-  }
-
-  private static void println() {
-    SCREEN_PRINTER.println();
-  }
-
-  static void println(String msg) {
-    SCREEN_PRINTER.println(msg);
-  }
-
   static boolean processCommand(String s, IoTDBConnection connection) {
     if (s == null) {
       return true;
diff --git a/cli/src/main/java/org/apache/iotdb/cli/Cli.java b/cli/src/main/java/org/apache/iotdb/cli/Cli.java
index 907aedf..abcd8de 100644
--- a/cli/src/main/java/org/apache/iotdb/cli/Cli.java
+++ b/cli/src/main/java/org/apache/iotdb/cli/Cli.java
@@ -18,6 +18,8 @@
  */
 package org.apache.iotdb.cli;
 
+import static org.apache.iotdb.cli.utils.IoTPrinter.println;
+
 import java.io.IOException;
 import java.sql.DriverManager;
 import java.sql.SQLException;
diff --git a/cli/src/main/java/org/apache/iotdb/cli/WinCli.java b/cli/src/main/java/org/apache/iotdb/cli/WinCli.java
index 53c7837..9a4b5de 100644
--- a/cli/src/main/java/org/apache/iotdb/cli/WinCli.java
+++ b/cli/src/main/java/org/apache/iotdb/cli/WinCli.java
@@ -18,6 +18,9 @@
  */
 package org.apache.iotdb.cli;
 
+import static org.apache.iotdb.cli.utils.IoTPrinter.print;
+import static org.apache.iotdb.cli.utils.IoTPrinter.println;
+
 import java.io.Console;
 import java.sql.DriverManager;
 import java.sql.SQLException;
diff --git a/cli/src/main/java/org/apache/iotdb/cli/utils/IoTPrinter.java b/cli/src/main/java/org/apache/iotdb/cli/utils/IoTPrinter.java
new file mode 100644
index 0000000..89b939b
--- /dev/null
+++ b/cli/src/main/java/org/apache/iotdb/cli/utils/IoTPrinter.java
@@ -0,0 +1,107 @@
+/*
+ * 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.utils;
+
+import java.io.PrintStream;
+import java.lang.Character.UnicodeScript;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+
+public class IoTPrinter {
+  private static final PrintStream SCREEN_PRINTER = new PrintStream(System.out);
+
+  public static void printf(String format, Object... args) {
+    SCREEN_PRINTER.printf(format, args);
+  }
+
+  public static void print(String msg) {
+    SCREEN_PRINTER.print(msg);
+  }
+
+  public static void println() {
+    SCREEN_PRINTER.println();
+  }
+
+  public static void println(String msg) {
+    SCREEN_PRINTER.println(msg);
+  }
+
+  public static void printBlockLine(List<Integer> maxSizeList) {
+    StringBuilder blockLine = new StringBuilder();
+    for (Integer integer : maxSizeList) {
+      blockLine.append("+").append(StringUtils.repeat("-", integer));
+    }
+    blockLine.append("+");
+    println(blockLine.toString());
+  }
+
+  public static void printRow(List<List<String>> lists, int i, List<Integer> maxSizeList) {
+    printf("|");
+    int count;
+    int maxSize;
+    String element;
+    StringBuilder paddingStr;
+    for (int j = 0; j < maxSizeList.size(); j++) {
+      maxSize = maxSizeList.get(j);
+      element = lists.get(j).get(i);
+      count = computeHANCount(element);
+
+      if (count > 0) {
+        int remain = maxSize - (element.length() + count);
+        if (remain > 0) {
+          paddingStr = padding(remain);
+          maxSize = maxSize - count;
+          element = paddingStr.append(element).toString();
+        } else if (remain == 0) {
+          maxSize = maxSize - count;
+        }
+      }
+
+      printf("%" + maxSize + "s|", element);
+    }
+    println();
+  }
+
+  public static void printCount(int cnt) {
+    if (cnt == 0) {
+      println("Empty set.");
+    } else {
+      println("Total line number = " + cnt);
+    }
+  }
+
+  public static StringBuilder padding(int count) {
+    StringBuilder sb = new StringBuilder();
+    for (int k = 0; k < count; k++) {
+      sb.append(' ');
+    }
+
+    return sb;
+  }
+
+  /**
+   * compute the number of Chinese characters included in the String
+   */
+  public static int computeHANCount(String s) {
+    return (int) s.codePoints()
+        .filter(codePoint -> UnicodeScript.of(codePoint) == UnicodeScript.HAN)
+        .count();
+  }
+
+}