diff --git a/src/.vuepress/sidebar/V2.0.x/en-Table.ts b/src/.vuepress/sidebar/V2.0.x/en-Table.ts index 1e8e5716c..0525331d2 100644 --- a/src/.vuepress/sidebar/V2.0.x/en-Table.ts +++ b/src/.vuepress/sidebar/V2.0.x/en-Table.ts @@ -121,6 +121,7 @@ export const enSidebar = { children: [ { text: 'Java Native API', link: 'Programming-Java-Native-API_apache' }, { text: 'Python Native API', link: 'Programming-Python-Native-API' }, + { text: 'C++ Native API', link: 'Programming-Cpp-Native-API' }, { text: 'JDBC', link: 'Programming-JDBC_apache' }, { text: 'RESTAPI V1 ', link: 'RestAPI-V1' }, ], diff --git a/src/.vuepress/sidebar/V2.0.x/zh-Table.ts b/src/.vuepress/sidebar/V2.0.x/zh-Table.ts index 789bd14f2..d82b86055 100644 --- a/src/.vuepress/sidebar/V2.0.x/zh-Table.ts +++ b/src/.vuepress/sidebar/V2.0.x/zh-Table.ts @@ -113,6 +113,7 @@ export const zhSidebar = { children: [ { text: 'Java原生接口', link: 'Programming-Java-Native-API_apache' }, { text: 'Python原生接口', link: 'Programming-Python-Native-API' }, + { text: 'C++原生接口', link: 'Programming-Cpp-Native-API' }, { text: 'JDBC', link: 'Programming-JDBC_apache' }, { text: 'RESTAPI V1 ', link: 'RestServiceV1' }, ], diff --git a/src/.vuepress/sidebar_timecho/V2.0.x/en-Table.ts b/src/.vuepress/sidebar_timecho/V2.0.x/en-Table.ts index 7a7d97153..86b3c4350 100644 --- a/src/.vuepress/sidebar_timecho/V2.0.x/en-Table.ts +++ b/src/.vuepress/sidebar_timecho/V2.0.x/en-Table.ts @@ -126,6 +126,7 @@ export const enSidebar = { children: [ { text: 'Java Native API', link: 'Programming-Java-Native-API_timecho' }, { text: 'Python Native API', link: 'Programming-Python-Native-API' }, + { text: 'C++ Native API', link: 'Programming-Cpp-Native-API' }, { text: 'JDBC', link: 'Programming-JDBC_timecho' }, { text: 'RESTAPI V1 ', link: 'RestAPI-V1' }, ], diff --git a/src/.vuepress/sidebar_timecho/V2.0.x/zh-Table.ts b/src/.vuepress/sidebar_timecho/V2.0.x/zh-Table.ts index 38628b0b3..63aa0c86a 100644 --- a/src/.vuepress/sidebar_timecho/V2.0.x/zh-Table.ts +++ b/src/.vuepress/sidebar_timecho/V2.0.x/zh-Table.ts @@ -117,6 +117,7 @@ export const zhSidebar = { children: [ { text: 'Java原生接口', link: 'Programming-Java-Native-API_timecho' }, { text: 'Python原生接口', link: 'Programming-Python-Native-API' }, + { text: 'C++原生接口', link: 'Programming-Cpp-Native-API' }, { text: 'JDBC', link: 'Programming-JDBC_timecho' }, { text: 'RESTAPI V1 ', link: 'RestServiceV1' }, ], diff --git a/src/UserGuide/Master/Table/API/Programming-Cpp-Native-API.md b/src/UserGuide/Master/Table/API/Programming-Cpp-Native-API.md new file mode 100644 index 000000000..a62bfc5a2 --- /dev/null +++ b/src/UserGuide/Master/Table/API/Programming-Cpp-Native-API.md @@ -0,0 +1,250 @@ + + +# C++ Native API + +## 1. Dependencies + +- Java 8+ +- Flex +- Bison 2.7+ +- Boost 1.56+ +- OpenSSL 1.0+ +- GCC 5.5.0+ + +## 2. Installation + +### 2.1 Install Required Dependencies + +- **MAC** + 1. Install Bison: + + Use the following brew command to install the Bison version: + ```shell + brew install bison + ``` + + 2. Install Boost: Make sure to install the latest version of Boost. + + ```shell + brew install boost + ``` + + 3. Check OpenSSL: Make sure the OpenSSL library is installed. The default OpenSSL header file path is "/usr/local/opt/openssl/include". + + If you encounter errors related to OpenSSL not being found during compilation, try adding `-Dopenssl.include.dir=""`. + +- **Ubuntu 16.04+ or Other Debian-based Systems** + + Use the following commands to install dependencies: + + ```shell + sudo apt-get update + sudo apt-get install gcc g++ bison flex libboost-all-dev libssl-dev + ``` + +- **CentOS 7.7+/Fedora/Rocky Linux or Other Red Hat-based Systems** + + Use the yum command to install dependencies: + + ```shell + sudo yum update + sudo yum install gcc gcc-c++ boost-devel bison flex openssl-devel + ``` + +- **Windows** + + 1. Set Up the Build Environment + - Install MS Visual Studio (version 2019+ recommended): Make sure to select Visual Studio C/C++ IDE and compiler (supporting CMake, Clang, MinGW) during installation. + - Download and install [CMake](https://cmake.org/download/). + + 2. Download and Install Flex, Bison + - Download [Win_Flex_Bison](https://sourceforge.net/projects/winflexbison/). + - After downloading, rename the executables to flex.exe and bison.exe to ensure they can be found during compilation, and add the directory of these executables to the PATH environment variable. + + 3. Install Boost Library + - Download [Boost](https://www.boost.org/users/download/). + - Compile Boost locally: Run `bootstrap.bat` and `b2.exe` in sequence. + - Add the Boost installation directory to the PATH environment variable, e.g., `C:\Program Files (x86)\boost_1_78_0`. + + 4. Install OpenSSL + - Download and install [OpenSSL](http://slproweb.com/products/Win32OpenSSL.html). + - Add the include directory under the installation directory to the PATH environment variable. + +### 2.2 Compilation + +Clone the source code from git: +```shell +git clone https://github.com/apache/iotdb.git +``` + +The default main branch is the master branch. If you want to use a specific release version, switch to that branch (e.g., version 1.3.2): +```shell +git checkout rc/1.3.2 +``` + +Run Maven to compile in the IoTDB root directory: + +- Mac or Linux with glibc version >= 2.32 + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp + ``` + +- Linux with glibc version >= 2.31 + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-old-glibc-SNAPSHOT + ``` + +- Linux with glibc version >= 2.17 + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-glibc223-SNAPSHOT + ``` + +- Windows using Visual Studio 2022 + ```batch + .\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp + ``` + +- Windows using Visual Studio 2019 + ```batch + .\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Dcmake.generator="Visual Studio 16 2019" -Diotdb-tools-thrift.version=0.14.1.1-msvc142-SNAPSHOT + ``` + - If you haven't added the Boost library path to the PATH environment variable, you need to add the relevant parameters to the compile command, e.g., `-DboostIncludeDir="C:\Program Files (x86)\boost_1_78_0" -DboostLibraryDir="C:\Program Files (x86)\boost_1_78_0\stage\lib"`. + +After successful compilation, the packaged library files will be located in `iotdb-client/client-cpp/target`, and you can find the compiled example program under `example/client-cpp-example/target`. + +### 2.3 Compilation Q&A + +Q: What are the requirements for the environment on Linux? + +A: +- The known minimum version requirement for glibc (x86_64 version) is 2.17, and the minimum version for GCC is 5.5. +- The known minimum version requirement for glibc (ARM version) is 2.31, and the minimum version for GCC is 10.2. +- If the above requirements are not met, you can try compiling Thrift locally: + - Download the code from https://github.com/apache/iotdb-bin-resources/tree/iotdb-tools-thrift-v0.14.1.0/iotdb-tools-thrift. + - Run `./mvnw clean install`. + - Go back to the IoTDB code directory and run `./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp`. + +Q: How to resolve the `undefined reference to '_libc_single_thread'` error during Linux compilation? + +A: +- This issue is caused by the precompiled Thrift dependencies requiring a higher version of glibc. +- You can try adding `-Diotdb-tools-thrift.version=0.14.1.1-glibc223-SNAPSHOT` or `-Diotdb-tools-thrift.version=0.14.1.1-old-glibc-SNAPSHOT` to the Maven compile command. + +Q: What if I need to compile using Visual Studio 2017 or earlier on Windows? + +A: +- You can try compiling Thrift locally before compiling the client: + - Download the code from https://github.com/apache/iotdb-bin-resources/tree/iotdb-tools-thrift-v0.14.1.0/iotdb-tools-thrift. + - Run `.\mvnw.cmd clean install`. + - Go back to the IoTDB code directory and run `.\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Dcmake.generator="Visual Studio 15 2017"`. + +## 3. Usage + +### 3.1 TableSession Class + +All operations in the C++ client are performed through the TableSession class. Below are the method descriptions defined in the TableSession interface. + +#### 3.1.1 Method List + +1. `insert(Tablet& tablet, bool sorted = false)`: Inserts a Tablet object containing time series data into the database. The sorted parameter indicates whether the rows in the tablet are already sorted by time. +2. `executeNonQueryStatement(string& sql)`: Executes non-query SQL statements, such as DDL (Data Definition Language) or DML (Data Manipulation Language) commands. +3. `executeQueryStatement(string& sql)`: Executes query SQL statements and returns a SessionDataSet object containing the query results. The optional timeoutInMs parameter indicates the timeout return time. +4. `open(bool enableRPCCompression = false)`: Opens the connection and determines whether to enable RPC compression (client state must match server state, disabled by default). +5. `close()`: Closes the connection. + +### 3.1.2 Interface Display + +```cpp +class TableSession { +private: + Session* session; +public: + TableSession(Session* session) { + this->session = session; + } + void insert(Tablet& tablet, bool sorted = false); + void executeNonQueryStatement(const std::string& sql); + unique_ptr executeQueryStatement(const std::string& sql); + unique_ptr executeQueryStatement(const std::string& sql, int64_t timeoutInMs); + string getDatabase(); //Get the currently selected database, can be replaced by executeNonQueryStatement + void open(bool enableRPCCompression = false); + void close(); +}; +``` + +### 3.2 TableSessionBuilder Class + +The TableSessionBuilder class is a builder used to configure and create instances of the TableSession class. Through it, you can conveniently set connection parameters, query parameters, and other settings when creating instances. + +#### 3.2.1 Usage Example + +```cpp +//Set connection IP, port, username, password +//The order of settings is arbitrary, just ensure build() is called last, the created instance is connected by default through open() +session = (new TableSessionBuilder()) + ->host("127.0.0.1") + ->rpcPort(6667) + ->username("root") + ->password("root") + ->build(); +``` + +#### 3.2.2 Configurable Parameter List + +| **Parameter Name** | **Description** | **Default Value** | +| :---: | :---: | :---: | +| host | Set the connected node IP | "127.0.0.1" ("localhost") | +| rpcPort | Set the connected node port | 6667 | +| username | Set the connection username | "root" | +| password | Set the connection password | "root" | +| zoneId | Set the ZoneId related to timezone | "" | +| fetchSize | Set the query result fetch size | 10000 | +| database | Set the target database name | "" | + +## 4. Examples + +The sample code of using these interfaces is in: + +- `example/client-cpp-example/src/TableSessionExample.cpp`: [TableSessionExample](https://github.com/apache/iotdb/tree/rc/2.0.1/example/client-cpp-example/src/TableSessionExample.cpp) + +If the compilation finishes successfully, the example project will be placed under `example/client-cpp-example/target` + +## 5. FAQ + +### 5.1 on Mac + +If errors occur when compiling thrift source code, try to downgrade your xcode-commandline from 12 to 11.5 + +see https://stackoverflow.com/questions/63592445/ld-unsupported-tapi-file-type-tapi-tbd-in-yaml-file/65518087#65518087 + + +### 5.2 on Windows + +When Building Thrift and downloading packages via "wget", a possible annoying issue may occur with +error message looks like: +```shell +Failed to delete cached file C:\Users\Administrator\.m2\repository\.cache\download-maven-plugin\index.ser +``` +Possible fixes: +- Try to delete the ".m2\repository\\.cache\" directory and try again. +- Add "\true\" configuration to the download-maven-plugin maven phase that complains this error. + diff --git a/src/UserGuide/latest-Table/API/Programming-Cpp-Native-API.md b/src/UserGuide/latest-Table/API/Programming-Cpp-Native-API.md new file mode 100644 index 000000000..a62bfc5a2 --- /dev/null +++ b/src/UserGuide/latest-Table/API/Programming-Cpp-Native-API.md @@ -0,0 +1,250 @@ + + +# C++ Native API + +## 1. Dependencies + +- Java 8+ +- Flex +- Bison 2.7+ +- Boost 1.56+ +- OpenSSL 1.0+ +- GCC 5.5.0+ + +## 2. Installation + +### 2.1 Install Required Dependencies + +- **MAC** + 1. Install Bison: + + Use the following brew command to install the Bison version: + ```shell + brew install bison + ``` + + 2. Install Boost: Make sure to install the latest version of Boost. + + ```shell + brew install boost + ``` + + 3. Check OpenSSL: Make sure the OpenSSL library is installed. The default OpenSSL header file path is "/usr/local/opt/openssl/include". + + If you encounter errors related to OpenSSL not being found during compilation, try adding `-Dopenssl.include.dir=""`. + +- **Ubuntu 16.04+ or Other Debian-based Systems** + + Use the following commands to install dependencies: + + ```shell + sudo apt-get update + sudo apt-get install gcc g++ bison flex libboost-all-dev libssl-dev + ``` + +- **CentOS 7.7+/Fedora/Rocky Linux or Other Red Hat-based Systems** + + Use the yum command to install dependencies: + + ```shell + sudo yum update + sudo yum install gcc gcc-c++ boost-devel bison flex openssl-devel + ``` + +- **Windows** + + 1. Set Up the Build Environment + - Install MS Visual Studio (version 2019+ recommended): Make sure to select Visual Studio C/C++ IDE and compiler (supporting CMake, Clang, MinGW) during installation. + - Download and install [CMake](https://cmake.org/download/). + + 2. Download and Install Flex, Bison + - Download [Win_Flex_Bison](https://sourceforge.net/projects/winflexbison/). + - After downloading, rename the executables to flex.exe and bison.exe to ensure they can be found during compilation, and add the directory of these executables to the PATH environment variable. + + 3. Install Boost Library + - Download [Boost](https://www.boost.org/users/download/). + - Compile Boost locally: Run `bootstrap.bat` and `b2.exe` in sequence. + - Add the Boost installation directory to the PATH environment variable, e.g., `C:\Program Files (x86)\boost_1_78_0`. + + 4. Install OpenSSL + - Download and install [OpenSSL](http://slproweb.com/products/Win32OpenSSL.html). + - Add the include directory under the installation directory to the PATH environment variable. + +### 2.2 Compilation + +Clone the source code from git: +```shell +git clone https://github.com/apache/iotdb.git +``` + +The default main branch is the master branch. If you want to use a specific release version, switch to that branch (e.g., version 1.3.2): +```shell +git checkout rc/1.3.2 +``` + +Run Maven to compile in the IoTDB root directory: + +- Mac or Linux with glibc version >= 2.32 + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp + ``` + +- Linux with glibc version >= 2.31 + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-old-glibc-SNAPSHOT + ``` + +- Linux with glibc version >= 2.17 + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-glibc223-SNAPSHOT + ``` + +- Windows using Visual Studio 2022 + ```batch + .\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp + ``` + +- Windows using Visual Studio 2019 + ```batch + .\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Dcmake.generator="Visual Studio 16 2019" -Diotdb-tools-thrift.version=0.14.1.1-msvc142-SNAPSHOT + ``` + - If you haven't added the Boost library path to the PATH environment variable, you need to add the relevant parameters to the compile command, e.g., `-DboostIncludeDir="C:\Program Files (x86)\boost_1_78_0" -DboostLibraryDir="C:\Program Files (x86)\boost_1_78_0\stage\lib"`. + +After successful compilation, the packaged library files will be located in `iotdb-client/client-cpp/target`, and you can find the compiled example program under `example/client-cpp-example/target`. + +### 2.3 Compilation Q&A + +Q: What are the requirements for the environment on Linux? + +A: +- The known minimum version requirement for glibc (x86_64 version) is 2.17, and the minimum version for GCC is 5.5. +- The known minimum version requirement for glibc (ARM version) is 2.31, and the minimum version for GCC is 10.2. +- If the above requirements are not met, you can try compiling Thrift locally: + - Download the code from https://github.com/apache/iotdb-bin-resources/tree/iotdb-tools-thrift-v0.14.1.0/iotdb-tools-thrift. + - Run `./mvnw clean install`. + - Go back to the IoTDB code directory and run `./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp`. + +Q: How to resolve the `undefined reference to '_libc_single_thread'` error during Linux compilation? + +A: +- This issue is caused by the precompiled Thrift dependencies requiring a higher version of glibc. +- You can try adding `-Diotdb-tools-thrift.version=0.14.1.1-glibc223-SNAPSHOT` or `-Diotdb-tools-thrift.version=0.14.1.1-old-glibc-SNAPSHOT` to the Maven compile command. + +Q: What if I need to compile using Visual Studio 2017 or earlier on Windows? + +A: +- You can try compiling Thrift locally before compiling the client: + - Download the code from https://github.com/apache/iotdb-bin-resources/tree/iotdb-tools-thrift-v0.14.1.0/iotdb-tools-thrift. + - Run `.\mvnw.cmd clean install`. + - Go back to the IoTDB code directory and run `.\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Dcmake.generator="Visual Studio 15 2017"`. + +## 3. Usage + +### 3.1 TableSession Class + +All operations in the C++ client are performed through the TableSession class. Below are the method descriptions defined in the TableSession interface. + +#### 3.1.1 Method List + +1. `insert(Tablet& tablet, bool sorted = false)`: Inserts a Tablet object containing time series data into the database. The sorted parameter indicates whether the rows in the tablet are already sorted by time. +2. `executeNonQueryStatement(string& sql)`: Executes non-query SQL statements, such as DDL (Data Definition Language) or DML (Data Manipulation Language) commands. +3. `executeQueryStatement(string& sql)`: Executes query SQL statements and returns a SessionDataSet object containing the query results. The optional timeoutInMs parameter indicates the timeout return time. +4. `open(bool enableRPCCompression = false)`: Opens the connection and determines whether to enable RPC compression (client state must match server state, disabled by default). +5. `close()`: Closes the connection. + +### 3.1.2 Interface Display + +```cpp +class TableSession { +private: + Session* session; +public: + TableSession(Session* session) { + this->session = session; + } + void insert(Tablet& tablet, bool sorted = false); + void executeNonQueryStatement(const std::string& sql); + unique_ptr executeQueryStatement(const std::string& sql); + unique_ptr executeQueryStatement(const std::string& sql, int64_t timeoutInMs); + string getDatabase(); //Get the currently selected database, can be replaced by executeNonQueryStatement + void open(bool enableRPCCompression = false); + void close(); +}; +``` + +### 3.2 TableSessionBuilder Class + +The TableSessionBuilder class is a builder used to configure and create instances of the TableSession class. Through it, you can conveniently set connection parameters, query parameters, and other settings when creating instances. + +#### 3.2.1 Usage Example + +```cpp +//Set connection IP, port, username, password +//The order of settings is arbitrary, just ensure build() is called last, the created instance is connected by default through open() +session = (new TableSessionBuilder()) + ->host("127.0.0.1") + ->rpcPort(6667) + ->username("root") + ->password("root") + ->build(); +``` + +#### 3.2.2 Configurable Parameter List + +| **Parameter Name** | **Description** | **Default Value** | +| :---: | :---: | :---: | +| host | Set the connected node IP | "127.0.0.1" ("localhost") | +| rpcPort | Set the connected node port | 6667 | +| username | Set the connection username | "root" | +| password | Set the connection password | "root" | +| zoneId | Set the ZoneId related to timezone | "" | +| fetchSize | Set the query result fetch size | 10000 | +| database | Set the target database name | "" | + +## 4. Examples + +The sample code of using these interfaces is in: + +- `example/client-cpp-example/src/TableSessionExample.cpp`: [TableSessionExample](https://github.com/apache/iotdb/tree/rc/2.0.1/example/client-cpp-example/src/TableSessionExample.cpp) + +If the compilation finishes successfully, the example project will be placed under `example/client-cpp-example/target` + +## 5. FAQ + +### 5.1 on Mac + +If errors occur when compiling thrift source code, try to downgrade your xcode-commandline from 12 to 11.5 + +see https://stackoverflow.com/questions/63592445/ld-unsupported-tapi-file-type-tapi-tbd-in-yaml-file/65518087#65518087 + + +### 5.2 on Windows + +When Building Thrift and downloading packages via "wget", a possible annoying issue may occur with +error message looks like: +```shell +Failed to delete cached file C:\Users\Administrator\.m2\repository\.cache\download-maven-plugin\index.ser +``` +Possible fixes: +- Try to delete the ".m2\repository\\.cache\" directory and try again. +- Add "\true\" configuration to the download-maven-plugin maven phase that complains this error. + diff --git a/src/zh/UserGuide/Master/Table/API/Programming-Cpp-Native-API.md b/src/zh/UserGuide/Master/Table/API/Programming-Cpp-Native-API.md new file mode 100644 index 000000000..12bc48ce9 --- /dev/null +++ b/src/zh/UserGuide/Master/Table/API/Programming-Cpp-Native-API.md @@ -0,0 +1,461 @@ + + +# C++ 原生接口 + +## 1. 依赖 + +- Java 8+ +- Flex +- Bison 2.7+ +- Boost 1.56+ +- OpenSSL 1.0+ +- GCC 5.5.0+ + + +## 2. 安装 + +### 2.1 安装相关依赖 + +- **MAC** + 1. 安装 Bison : + + 使用下面 brew 命令安装 bison 版本: + ```shell + brew install bison + ``` + + 2. 安装 Boost :确保安装最新的 Boost 版本。 + + ```shell + brew install boost + ``` + + 3. 检查 OpenSSL :确保 openssl 库已安装,默认的 openssl 头文件路径为"/usr/local/opt/openssl/include" + + 如果在编译过程中出现找不到 openssl 的错误,尝试添加`-Dopenssl.include.dir=""` + + +- **Ubuntu 16.04+ 或其他 Debian 系列** + + 使用以下命令安装所赖: + + ```shell + sudo apt-get update + sudo apt-get install gcc g++ bison flex libboost-all-dev libssl-dev + ``` + + +- **CentOS 7.7+/Fedora/Rocky Linux 或其他 Red-hat 系列** + + 使用 yum 命令安装依赖: + + ```shell + sudo yum update + sudo yum install gcc gcc-c++ boost-devel bison flex openssl-devel + ``` + + +- **Windows** + +1. 构建编译环境 + - 安装 MS Visual Studio(推荐安装 2019+ 版本):安装时需要勾选 Visual Studio C/C++ IDE and compiler(supporting CMake, Clang, MinGW) + - 下载安装 [CMake](https://cmake.org/download/) 。 + +2. 下载安装 Flex、Bison + - 下载 [Win_Flex_Bison](https://sourceforge.net/projects/winflexbison/) + - 下载后需要将可执行文件重命名为 flex.exe 和 bison.exe 以保证编译时能够被找到,添加可执行文件的目录到 PATH 环境变量中 + +3. 安装 Boost 库 + - 下载 [Boost](https://www.boost.org/users/download/) + - 本地编译 Boost :依次执行 bootstrap.bat 和 b2.exe + - 添加 Boost 安装目录到 PATH 环境变量中,例如 `C:\Program Files (x86)\boost_1_78_0` + +4. 安装 OpenSSL + - 下载安装 [OpenSSL](http://slproweb.com/products/Win32OpenSSL.html) + - 添加 OpenSSL 下的 include 目录到 PATH 环境变量中 + + +### 2.2 执行编译 + +从 git 克隆源代码: +```shell +git clone https://github.com/apache/iotdb.git +``` + +默认的主分支是 master 分支,如果你想使用某个发布版本,请切换分支 (如 1.3.2 版本): +```shell +git checkout rc/1.3.2 +``` + +在 IoTDB 根目录下执行 maven 编译: + +- Mac 或 glibc 版本 >= 2.32 的 Linux + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp + ``` + +- glibc 版本 >= 2.31 的 Linux + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-old-glibc-SNAPSHOT + ``` + +- glibc 版本 >= 2.17 的 Linux + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-glibc223-SNAPSHOT + ``` + +- 使用 Visual Studio 2022 的 Windows + ```batch + .\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp + ``` + +- 使用 Visual Studio 2019 的 Windows + ```batch + .\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Dcmake.generator="Visual Studio 16 2019" -Diotdb-tools-thrift.version=0.14.1.1-msvc142-SNAPSHOT + ``` + - 如果没有将 Boost 库地址加入 PATH 环境变量,在编译命令中还需添加相关参数,例如:`-DboostIncludeDir="C:\Program Files (x86)\boost_1_78_0" -DboostLibraryDir="C:\Program Files (x86)\boost_1_78_0\stage\lib"` + +编译成功后,打包好的库文件位于 `iotdb-client/client-cpp/target` 中,同时可以在 `example/client-cpp-example/target` 下找到编译好的示例程序。 + +### 2.3 编译 Q&A + +Q:Linux 上的环境有哪些要求呢? + +A: +- 已知依赖的 glibc (x86_64 版本) 最低版本要求为 2.17,GCC 最低版本为 5.5 +- 已知依赖的 glibc (ARM 版本) 最低版本要求为 2.31,GCC 最低版本为 10.2 +- 如果不满足上面的要求,可以尝试自己本地编译 Thrift + - 下载 https://github.com/apache/iotdb-bin-resources/tree/iotdb-tools-thrift-v0.14.1.0/iotdb-tools-thrift 这里的代码 + - 执行 `./mvnw clean install` + - 回到 iotdb 代码目录执行 `./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp` + + +Q:Linux 编译报错`undefined reference to '_libc_sinle_thread'`如何处理? + +A: +- 该问题是用于默认的预编译 Thrift 依赖了过高的 glibc 版本导致的 +- 可以尝试在编译的 maven 命令中增加 `-Diotdb-tools-thrift.version=0.14.1.1-glibc223-SNAPSHOT` 或者 `-Diotdb-tools-thrift.version=0.14.1.1-old-glibc-SNAPSHOT` + +Q:如果在 Windows 上需要使用 Visual Studio 2017 或更早版本进行编译,要怎么做? + +A: +- 可以尝试自己本地编译 Thrift 后再进行客户端的编译 + - 下载 https://github.com/apache/iotdb-bin-resources/tree/iotdb-tools-thrift-v0.14.1.0/iotdb-tools-thrift 这里的代码 + - 执行 `.\mvnw.cmd clean install` + - 回到 iotdb 代码目录执行 `.\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Dcmake.generator="Visual Studio 15 2017"` + +Q: Windows 上使用 Visual Studio 进行编译时出现乱码,如何解决? + +A: +- 该问题是由于项目整体使用 utf-8 编码,而编译用到的一些 windows 系统文件编码不是 utf-8(系统编码默认跟随地区,在中国为 GBK) +- 可以在控制面板中更改系统区域设置,具体操作方法为:打开控制面板 -> 时钟和区域 -> 区域,切换到管理选项卡,在 "非Unicode程序的语言" 下,选择更改系统区域设置,勾选 `Beta版:使用Unicode UTF-8提供全球语言支持` 后重启电脑。(细节可能随windows版本有差异,可在网上寻找详细教程) +- 注意,修改 windows 系统编码后可能会导致一些其他使用 GBK 编码的程序出现乱码,将系统区域改回后可复原,请自行斟酌。 + +## 3. 使用方式 + +### 3.1 TableSession 类 + +C++ 客户端的操作均通过 TableSession 类进行,下面将给出 TableSession 接口中定义的方法说明。 + +#### 3.1.1 方法列表 + +1. `insert(Tablet& tablet, bool sorted = false)`,将一个包含时间序列数据的Tablet对象插入到数据库中,sorted参数指明tablet中的行是否已按时间排序。 +2. `executeNonQueryStatement(string& sql)`,执行非查询SQL语句,如DDL(数据定义语言)或DML(数据操作语言)命令。 +3. `executeQueryStatement(string& sql)`,执行查询SQL语句,并返回包含查询结果的SessionDataSet对象,可选timeoutInMs参数指示超时返回时间。 +4. `open(bool enableRPCCompression = false)`,开启连接,并决定是否启用RPC压缩(客户端状态须与服务端一致,默认不开启)。 +5. `close()`,关闭连接。 + +### 3.1.2 接口展示 + +```cpp +class TableSession { +private: + Session* session; +public: + TableSession(Session* session) { + this->session = session; + } + void insert(Tablet& tablet, bool sorted = false); + void executeNonQueryStatement(const std::string& sql); + unique_ptr executeQueryStatement(const std::string& sql); + unique_ptr executeQueryStatement(const std::string& sql, int64_t timeoutInMs); + string getDatabase(); //获取当前选择的database,可由executeNonQueryStatement代替 + void open(bool enableRPCCompression = false); + void close(); +}; +``` + +### 3.2 TableSessionBuilder 类 + +TableSessionBuilder类是一个构建器,用于配置和创建TableSession类的实例,通过它可以在创建实例时方便地设置连接参数、查询参数等。 + +#### 3.2.1 使用示例 + +```cpp +//设置连接的IP、端口、用户名、密码 +//设置的顺序任意,确保最后调用build()即可,创建的实例默认已进行open()连接操作 +session = (new TableSessionBuilder()) + ->host("127.0.0.1") + ->rpcPort(6667) + ->username("root") + ->password("root") + ->build(); +``` + +#### 3.2.2 可设置的参数列表 + +| **参数名** | **描述** | **默认值** | +| :---: | :---: | :---: | +| host | 设置连接的节点IP | "127.0.0.1" ("localhost") | +| rpcPort | 设置连接的节点端口 | 6667 | +| username | 设置连接的用户名 | "root" | +| password | 设置连接密码 | "root" | +| zoneId | 设置时区相关的ZoneId | "" | +| fetchSize | 设置查询结果的获取大小 | 10000 | +| database | 设置目标数据库名称 | "" | + + +## 4. 示例代码 + +示例工程源代码: + +- `example/client-cpp-example/src/TableModelSessionExample.cpp` : [TableModelSessionExample](https://github.com/apache/iotdb/tree/rc/2.0.1/example/client-cpp-example/src/TableModelSessionExample.cpp) + +编译成功后,示例代码工程位于 `example/client-cpp-example/target` + +```cpp +#include "TableSession.h" +#include "TableSessionBuilder.h" + +using namespace std; + +TableSession *session; + +void insertRelationalTablet() { + + vector> schemaList { + make_pair("region_id", TSDataType::TEXT), + make_pair("plant_id", TSDataType::TEXT), + make_pair("device_id", TSDataType::TEXT), + make_pair("model", TSDataType::TEXT), + make_pair("temperature", TSDataType::FLOAT), + make_pair("humidity", TSDataType::DOUBLE) + }; + + vector columnTypes = { + ColumnCategory::TAG, + ColumnCategory::TAG, + ColumnCategory::TAG, + ColumnCategory::ATTRIBUTE, + ColumnCategory::FIELD, + ColumnCategory::FIELD + }; + + Tablet tablet("table1", schemaList, columnTypes, 100); + + for (int row = 0; row < 100; row++) { + int rowIndex = tablet.rowSize++; + tablet.timestamps[rowIndex] = row; + tablet.addValue("region_id", rowIndex, "1"); + tablet.addValue("plant_id", rowIndex, "5"); + tablet.addValue("device_id", rowIndex, "3"); + tablet.addValue("model", rowIndex, "A"); + tablet.addValue("temperature", rowIndex, 37.6F); + tablet.addValue("humidity", rowIndex, 111.1); + if (tablet.rowSize == tablet.maxRowNumber) { + session->insert(tablet); + tablet.reset(); + } + } + + if (tablet.rowSize != 0) { + session->insert(tablet); + tablet.reset(); + } +} + +void Output(unique_ptr &dataSet) { + for (const string &name: dataSet->getColumnNames()) { + cout << name << " "; + } + cout << endl; + while (dataSet->hasNext()) { + cout << dataSet->next()->toString(); + // 可通过 RowRecord* row = dataSet->next(); + // for(auto field: row.fields) field.intV/longV/stringV 来获取值 + } + cout << endl; +} + +void OutputWithType(unique_ptr &dataSet) { + for (const string &name: dataSet->getColumnNames()) { + cout << name << " "; + } + cout << endl; + for (const string &type: dataSet->getColumnTypeList()) { + cout << type << " "; + } + cout << endl; + while (dataSet->hasNext()) { + cout << dataSet->next()->toString(); + } + cout << endl; +} + +int main() { + try { + session = (new TableSessionBuilder()) + ->host("127.0.0.1") + ->rpcPort(6667) + ->username("root") + ->password("root") + ->build(); + + + cout << "[Create Database db1,db2]\n" << endl; + try { + session->executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS db1"); + session->executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS db2"); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Use db1 as database]\n" << endl; + try { + session->executeNonQueryStatement("USE db1"); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Create Table table1,table2]\n" << endl; + try { + session->executeNonQueryStatement("create table db1.table1(region_id STRING TAG, plant_id STRING TAG, device_id STRING TAG, model STRING ATTRIBUTE, temperature FLOAT FIELD, humidity DOUBLE FIELD) with (TTL=3600000)"); + session->executeNonQueryStatement("create table db2.table2(region_id STRING TAG, plant_id STRING TAG, color STRING ATTRIBUTE, temperature FLOAT FIELD, speed DOUBLE FIELD) with (TTL=6600000)"); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Show Tables]\n" << endl; + try { + unique_ptr dataSet = session->executeQueryStatement("SHOW TABLES"); + Output(dataSet); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Show tables from specific database]\n" << endl; + try { + unique_ptr dataSet = session->executeQueryStatement("SHOW TABLES FROM db1"); + Output(dataSet); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[InsertTablet]\n" << endl; + try { + insertRelationalTablet(); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Query Table Data]\n" << endl; + try { + unique_ptr dataSet = session->executeQueryStatement("SELECT * FROM table1" + " where region_id = '1' and plant_id in ('3', '5') and device_id = '3'"); + OutputWithType(dataSet); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + session->close(); + + // specify database in constructor + session = (new TableSessionBuilder()) + ->host("127.0.0.1") + ->rpcPort(6667) + ->username("root") + ->password("root") + ->database("db1") + ->build(); + + cout << "[Show tables from current database(db1)]\n" << endl; + try { + unique_ptr dataSet = session->executeQueryStatement("SHOW TABLES"); + Output(dataSet); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Change database to db2]\n" << endl; + try { + session->executeNonQueryStatement("USE db2"); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Show tables from current database(db2)]\n" << endl; + try { + unique_ptr dataSet = session->executeQueryStatement("SHOW TABLES"); + Output(dataSet); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Drop Database db1,db2]\n" << endl; + try { + session->executeNonQueryStatement("DROP DATABASE db1"); + session->executeNonQueryStatement("DROP DATABASE db2"); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "session close\n" << endl; + session->close(); + + delete session; + + cout << "finished!\n" << endl; + } catch (IoTDBConnectionException &e) { + cout << e.what() << endl; + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + return 0; +} +``` + +## 5. FAQ + +### 5.1 Thrift 编译相关问题 + +1. MAC:本地 Maven 编译 Thrift 时如出现以下链接的问题,可以尝试将 xcode-commandline 版本从 12 降低到 11.5 + https://stackoverflow.com/questions/63592445/ld-unsupported-tapi-file-type-tapi-tbd-in-yaml-file/65518087#65518087 + + +2. Windows:Maven 编译 Thrift 时需要使用 wget 下载远端文件,可能出现以下报错: + ``` + Failed to delete cached file C:\Users\Administrator\.m2\repository\.cache\download-maven-plugin\index.ser + ``` + + 解决方法: + - 尝试删除 ".m2\repository\\.cache\" 目录并重试。 + - 在添加 pom 文件对应的 download-maven-plugin 中添加 "\true\" diff --git a/src/zh/UserGuide/latest-Table/API/Programming-Cpp-Native-API.md b/src/zh/UserGuide/latest-Table/API/Programming-Cpp-Native-API.md new file mode 100644 index 000000000..12bc48ce9 --- /dev/null +++ b/src/zh/UserGuide/latest-Table/API/Programming-Cpp-Native-API.md @@ -0,0 +1,461 @@ + + +# C++ 原生接口 + +## 1. 依赖 + +- Java 8+ +- Flex +- Bison 2.7+ +- Boost 1.56+ +- OpenSSL 1.0+ +- GCC 5.5.0+ + + +## 2. 安装 + +### 2.1 安装相关依赖 + +- **MAC** + 1. 安装 Bison : + + 使用下面 brew 命令安装 bison 版本: + ```shell + brew install bison + ``` + + 2. 安装 Boost :确保安装最新的 Boost 版本。 + + ```shell + brew install boost + ``` + + 3. 检查 OpenSSL :确保 openssl 库已安装,默认的 openssl 头文件路径为"/usr/local/opt/openssl/include" + + 如果在编译过程中出现找不到 openssl 的错误,尝试添加`-Dopenssl.include.dir=""` + + +- **Ubuntu 16.04+ 或其他 Debian 系列** + + 使用以下命令安装所赖: + + ```shell + sudo apt-get update + sudo apt-get install gcc g++ bison flex libboost-all-dev libssl-dev + ``` + + +- **CentOS 7.7+/Fedora/Rocky Linux 或其他 Red-hat 系列** + + 使用 yum 命令安装依赖: + + ```shell + sudo yum update + sudo yum install gcc gcc-c++ boost-devel bison flex openssl-devel + ``` + + +- **Windows** + +1. 构建编译环境 + - 安装 MS Visual Studio(推荐安装 2019+ 版本):安装时需要勾选 Visual Studio C/C++ IDE and compiler(supporting CMake, Clang, MinGW) + - 下载安装 [CMake](https://cmake.org/download/) 。 + +2. 下载安装 Flex、Bison + - 下载 [Win_Flex_Bison](https://sourceforge.net/projects/winflexbison/) + - 下载后需要将可执行文件重命名为 flex.exe 和 bison.exe 以保证编译时能够被找到,添加可执行文件的目录到 PATH 环境变量中 + +3. 安装 Boost 库 + - 下载 [Boost](https://www.boost.org/users/download/) + - 本地编译 Boost :依次执行 bootstrap.bat 和 b2.exe + - 添加 Boost 安装目录到 PATH 环境变量中,例如 `C:\Program Files (x86)\boost_1_78_0` + +4. 安装 OpenSSL + - 下载安装 [OpenSSL](http://slproweb.com/products/Win32OpenSSL.html) + - 添加 OpenSSL 下的 include 目录到 PATH 环境变量中 + + +### 2.2 执行编译 + +从 git 克隆源代码: +```shell +git clone https://github.com/apache/iotdb.git +``` + +默认的主分支是 master 分支,如果你想使用某个发布版本,请切换分支 (如 1.3.2 版本): +```shell +git checkout rc/1.3.2 +``` + +在 IoTDB 根目录下执行 maven 编译: + +- Mac 或 glibc 版本 >= 2.32 的 Linux + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp + ``` + +- glibc 版本 >= 2.31 的 Linux + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-old-glibc-SNAPSHOT + ``` + +- glibc 版本 >= 2.17 的 Linux + ```shell + ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-glibc223-SNAPSHOT + ``` + +- 使用 Visual Studio 2022 的 Windows + ```batch + .\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp + ``` + +- 使用 Visual Studio 2019 的 Windows + ```batch + .\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Dcmake.generator="Visual Studio 16 2019" -Diotdb-tools-thrift.version=0.14.1.1-msvc142-SNAPSHOT + ``` + - 如果没有将 Boost 库地址加入 PATH 环境变量,在编译命令中还需添加相关参数,例如:`-DboostIncludeDir="C:\Program Files (x86)\boost_1_78_0" -DboostLibraryDir="C:\Program Files (x86)\boost_1_78_0\stage\lib"` + +编译成功后,打包好的库文件位于 `iotdb-client/client-cpp/target` 中,同时可以在 `example/client-cpp-example/target` 下找到编译好的示例程序。 + +### 2.3 编译 Q&A + +Q:Linux 上的环境有哪些要求呢? + +A: +- 已知依赖的 glibc (x86_64 版本) 最低版本要求为 2.17,GCC 最低版本为 5.5 +- 已知依赖的 glibc (ARM 版本) 最低版本要求为 2.31,GCC 最低版本为 10.2 +- 如果不满足上面的要求,可以尝试自己本地编译 Thrift + - 下载 https://github.com/apache/iotdb-bin-resources/tree/iotdb-tools-thrift-v0.14.1.0/iotdb-tools-thrift 这里的代码 + - 执行 `./mvnw clean install` + - 回到 iotdb 代码目录执行 `./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp` + + +Q:Linux 编译报错`undefined reference to '_libc_sinle_thread'`如何处理? + +A: +- 该问题是用于默认的预编译 Thrift 依赖了过高的 glibc 版本导致的 +- 可以尝试在编译的 maven 命令中增加 `-Diotdb-tools-thrift.version=0.14.1.1-glibc223-SNAPSHOT` 或者 `-Diotdb-tools-thrift.version=0.14.1.1-old-glibc-SNAPSHOT` + +Q:如果在 Windows 上需要使用 Visual Studio 2017 或更早版本进行编译,要怎么做? + +A: +- 可以尝试自己本地编译 Thrift 后再进行客户端的编译 + - 下载 https://github.com/apache/iotdb-bin-resources/tree/iotdb-tools-thrift-v0.14.1.0/iotdb-tools-thrift 这里的代码 + - 执行 `.\mvnw.cmd clean install` + - 回到 iotdb 代码目录执行 `.\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Dcmake.generator="Visual Studio 15 2017"` + +Q: Windows 上使用 Visual Studio 进行编译时出现乱码,如何解决? + +A: +- 该问题是由于项目整体使用 utf-8 编码,而编译用到的一些 windows 系统文件编码不是 utf-8(系统编码默认跟随地区,在中国为 GBK) +- 可以在控制面板中更改系统区域设置,具体操作方法为:打开控制面板 -> 时钟和区域 -> 区域,切换到管理选项卡,在 "非Unicode程序的语言" 下,选择更改系统区域设置,勾选 `Beta版:使用Unicode UTF-8提供全球语言支持` 后重启电脑。(细节可能随windows版本有差异,可在网上寻找详细教程) +- 注意,修改 windows 系统编码后可能会导致一些其他使用 GBK 编码的程序出现乱码,将系统区域改回后可复原,请自行斟酌。 + +## 3. 使用方式 + +### 3.1 TableSession 类 + +C++ 客户端的操作均通过 TableSession 类进行,下面将给出 TableSession 接口中定义的方法说明。 + +#### 3.1.1 方法列表 + +1. `insert(Tablet& tablet, bool sorted = false)`,将一个包含时间序列数据的Tablet对象插入到数据库中,sorted参数指明tablet中的行是否已按时间排序。 +2. `executeNonQueryStatement(string& sql)`,执行非查询SQL语句,如DDL(数据定义语言)或DML(数据操作语言)命令。 +3. `executeQueryStatement(string& sql)`,执行查询SQL语句,并返回包含查询结果的SessionDataSet对象,可选timeoutInMs参数指示超时返回时间。 +4. `open(bool enableRPCCompression = false)`,开启连接,并决定是否启用RPC压缩(客户端状态须与服务端一致,默认不开启)。 +5. `close()`,关闭连接。 + +### 3.1.2 接口展示 + +```cpp +class TableSession { +private: + Session* session; +public: + TableSession(Session* session) { + this->session = session; + } + void insert(Tablet& tablet, bool sorted = false); + void executeNonQueryStatement(const std::string& sql); + unique_ptr executeQueryStatement(const std::string& sql); + unique_ptr executeQueryStatement(const std::string& sql, int64_t timeoutInMs); + string getDatabase(); //获取当前选择的database,可由executeNonQueryStatement代替 + void open(bool enableRPCCompression = false); + void close(); +}; +``` + +### 3.2 TableSessionBuilder 类 + +TableSessionBuilder类是一个构建器,用于配置和创建TableSession类的实例,通过它可以在创建实例时方便地设置连接参数、查询参数等。 + +#### 3.2.1 使用示例 + +```cpp +//设置连接的IP、端口、用户名、密码 +//设置的顺序任意,确保最后调用build()即可,创建的实例默认已进行open()连接操作 +session = (new TableSessionBuilder()) + ->host("127.0.0.1") + ->rpcPort(6667) + ->username("root") + ->password("root") + ->build(); +``` + +#### 3.2.2 可设置的参数列表 + +| **参数名** | **描述** | **默认值** | +| :---: | :---: | :---: | +| host | 设置连接的节点IP | "127.0.0.1" ("localhost") | +| rpcPort | 设置连接的节点端口 | 6667 | +| username | 设置连接的用户名 | "root" | +| password | 设置连接密码 | "root" | +| zoneId | 设置时区相关的ZoneId | "" | +| fetchSize | 设置查询结果的获取大小 | 10000 | +| database | 设置目标数据库名称 | "" | + + +## 4. 示例代码 + +示例工程源代码: + +- `example/client-cpp-example/src/TableModelSessionExample.cpp` : [TableModelSessionExample](https://github.com/apache/iotdb/tree/rc/2.0.1/example/client-cpp-example/src/TableModelSessionExample.cpp) + +编译成功后,示例代码工程位于 `example/client-cpp-example/target` + +```cpp +#include "TableSession.h" +#include "TableSessionBuilder.h" + +using namespace std; + +TableSession *session; + +void insertRelationalTablet() { + + vector> schemaList { + make_pair("region_id", TSDataType::TEXT), + make_pair("plant_id", TSDataType::TEXT), + make_pair("device_id", TSDataType::TEXT), + make_pair("model", TSDataType::TEXT), + make_pair("temperature", TSDataType::FLOAT), + make_pair("humidity", TSDataType::DOUBLE) + }; + + vector columnTypes = { + ColumnCategory::TAG, + ColumnCategory::TAG, + ColumnCategory::TAG, + ColumnCategory::ATTRIBUTE, + ColumnCategory::FIELD, + ColumnCategory::FIELD + }; + + Tablet tablet("table1", schemaList, columnTypes, 100); + + for (int row = 0; row < 100; row++) { + int rowIndex = tablet.rowSize++; + tablet.timestamps[rowIndex] = row; + tablet.addValue("region_id", rowIndex, "1"); + tablet.addValue("plant_id", rowIndex, "5"); + tablet.addValue("device_id", rowIndex, "3"); + tablet.addValue("model", rowIndex, "A"); + tablet.addValue("temperature", rowIndex, 37.6F); + tablet.addValue("humidity", rowIndex, 111.1); + if (tablet.rowSize == tablet.maxRowNumber) { + session->insert(tablet); + tablet.reset(); + } + } + + if (tablet.rowSize != 0) { + session->insert(tablet); + tablet.reset(); + } +} + +void Output(unique_ptr &dataSet) { + for (const string &name: dataSet->getColumnNames()) { + cout << name << " "; + } + cout << endl; + while (dataSet->hasNext()) { + cout << dataSet->next()->toString(); + // 可通过 RowRecord* row = dataSet->next(); + // for(auto field: row.fields) field.intV/longV/stringV 来获取值 + } + cout << endl; +} + +void OutputWithType(unique_ptr &dataSet) { + for (const string &name: dataSet->getColumnNames()) { + cout << name << " "; + } + cout << endl; + for (const string &type: dataSet->getColumnTypeList()) { + cout << type << " "; + } + cout << endl; + while (dataSet->hasNext()) { + cout << dataSet->next()->toString(); + } + cout << endl; +} + +int main() { + try { + session = (new TableSessionBuilder()) + ->host("127.0.0.1") + ->rpcPort(6667) + ->username("root") + ->password("root") + ->build(); + + + cout << "[Create Database db1,db2]\n" << endl; + try { + session->executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS db1"); + session->executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS db2"); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Use db1 as database]\n" << endl; + try { + session->executeNonQueryStatement("USE db1"); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Create Table table1,table2]\n" << endl; + try { + session->executeNonQueryStatement("create table db1.table1(region_id STRING TAG, plant_id STRING TAG, device_id STRING TAG, model STRING ATTRIBUTE, temperature FLOAT FIELD, humidity DOUBLE FIELD) with (TTL=3600000)"); + session->executeNonQueryStatement("create table db2.table2(region_id STRING TAG, plant_id STRING TAG, color STRING ATTRIBUTE, temperature FLOAT FIELD, speed DOUBLE FIELD) with (TTL=6600000)"); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Show Tables]\n" << endl; + try { + unique_ptr dataSet = session->executeQueryStatement("SHOW TABLES"); + Output(dataSet); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Show tables from specific database]\n" << endl; + try { + unique_ptr dataSet = session->executeQueryStatement("SHOW TABLES FROM db1"); + Output(dataSet); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[InsertTablet]\n" << endl; + try { + insertRelationalTablet(); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Query Table Data]\n" << endl; + try { + unique_ptr dataSet = session->executeQueryStatement("SELECT * FROM table1" + " where region_id = '1' and plant_id in ('3', '5') and device_id = '3'"); + OutputWithType(dataSet); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + session->close(); + + // specify database in constructor + session = (new TableSessionBuilder()) + ->host("127.0.0.1") + ->rpcPort(6667) + ->username("root") + ->password("root") + ->database("db1") + ->build(); + + cout << "[Show tables from current database(db1)]\n" << endl; + try { + unique_ptr dataSet = session->executeQueryStatement("SHOW TABLES"); + Output(dataSet); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Change database to db2]\n" << endl; + try { + session->executeNonQueryStatement("USE db2"); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Show tables from current database(db2)]\n" << endl; + try { + unique_ptr dataSet = session->executeQueryStatement("SHOW TABLES"); + Output(dataSet); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "[Drop Database db1,db2]\n" << endl; + try { + session->executeNonQueryStatement("DROP DATABASE db1"); + session->executeNonQueryStatement("DROP DATABASE db2"); + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + + cout << "session close\n" << endl; + session->close(); + + delete session; + + cout << "finished!\n" << endl; + } catch (IoTDBConnectionException &e) { + cout << e.what() << endl; + } catch (IoTDBException &e) { + cout << e.what() << endl; + } + return 0; +} +``` + +## 5. FAQ + +### 5.1 Thrift 编译相关问题 + +1. MAC:本地 Maven 编译 Thrift 时如出现以下链接的问题,可以尝试将 xcode-commandline 版本从 12 降低到 11.5 + https://stackoverflow.com/questions/63592445/ld-unsupported-tapi-file-type-tapi-tbd-in-yaml-file/65518087#65518087 + + +2. Windows:Maven 编译 Thrift 时需要使用 wget 下载远端文件,可能出现以下报错: + ``` + Failed to delete cached file C:\Users\Administrator\.m2\repository\.cache\download-maven-plugin\index.ser + ``` + + 解决方法: + - 尝试删除 ".m2\repository\\.cache\" 目录并重试。 + - 在添加 pom 文件对应的 download-maven-plugin 中添加 "\true\"