安装 Bison :
使用下面 brew 命令安装 bison 版本:
brew install bison
安装 Boost :确保安装最新的 Boost 版本。
brew install boost
检查 OpenSSL :确保 openssl 库已安装,默认的 openssl 头文件路径为"/usr/local/opt/openssl/include"
如果在编译过程中出现找不到 openssl 的错误,尝试添加-Dopenssl.include.dir=""
Ubuntu 16.04+ 或其他 Debian 系列
使用以下命令安装所赖:
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 命令安装依赖:
sudo yum update sudo yum install gcc gcc-c++ boost-devel bison flex openssl-devel
Windows
构建编译环境
下载安装 Flex、Bison
安装 Boost 库
C:\Program Files (x86)\boost_1_78_0安装 OpenSSL
从 git 克隆源代码:
git clone https://github.com/apache/iotdb.git
默认的主分支是 master 分支,如果你想使用某个发布版本,请切换分支 (如 1.3.2 版本):
git checkout rc/1.3.2
在 IoTDB 根目录下执行 maven 编译:
Mac 或 glibc 版本 >= 2.32 的 Linux
./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp
glibc 版本 >= 2.31 的 Linux
./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
./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
.\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp
使用 Visual Studio 2019 的 Windows
.\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
-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 下找到编译好的示例程序。
Q:Linux 上的环境有哪些要求呢?
A:
./mvnw clean install./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cppQ:Linux 编译报错undefined reference to '_libc_sinle_thread'如何处理?
A:
-Diotdb-tools-thrift.version=0.14.1.1-glibc223-SNAPSHOT 或者 -Diotdb-tools-thrift.version=0.14.1.1-old-glibc-SNAPSHOTQ:如果在 Windows 上需要使用 Visual Studio 2017 或更早版本进行编译,要怎么做?
A:
.\mvnw.cmd clean install.\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:
Beta版:使用Unicode UTF-8提供全球语言支持 后重启电脑。(细节可能随windows版本有差异,可在网上寻找详细教程)C++ 客户端的操作均通过 TableSession 类进行,下面将给出 TableSession 接口中定义的方法说明。
insert(Tablet& tablet, bool sorted = false),将一个包含时间序列数据的Tablet对象插入到数据库中,sorted参数指明tablet中的行是否已按时间排序。executeNonQueryStatement(string& sql),执行非查询SQL语句,如DDL(数据定义语言)或DML(数据操作语言)命令。executeQueryStatement(string& sql),执行查询SQL语句,并返回包含查询结果的SessionDataSet对象,可选timeoutInMs参数指示超时返回时间。open(bool enableRPCCompression = false),开启连接,并决定是否启用RPC压缩(客户端状态须与服务端一致,默认不开启)。close(),关闭连接。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<SessionDataSet> executeQueryStatement(const std::string& sql); unique_ptr<SessionDataSet> executeQueryStatement(const std::string& sql, int64_t timeoutInMs); string getDatabase(); //获取当前选择的database,可由executeNonQueryStatement代替 void open(bool enableRPCCompression = false); void close(); };
TableSessionBuilder类是一个构建器,用于配置和创建TableSession类的实例,通过它可以在创建实例时方便地设置连接参数、查询参数等。
//设置连接的IP、端口、用户名、密码 //设置的顺序任意,确保最后调用build()即可,创建的实例默认已进行open()连接操作 session = (new TableSessionBuilder()) ->host("127.0.0.1") ->rpcPort(6667) ->username("root") ->password("TimechoDB@2021") //V2.0.6.x 之前默认密码是root ->build();
| 参数名 | 描述 | 默认值 |
|---|---|---|
| host | 设置连接的节点IP | “127.0.0.1” (“localhost”) |
| rpcPort | 设置连接的节点端口 | 6667 |
| username | 设置连接的用户名 | “root” |
| password | 设置连接密码 | “TimechoDB@2021” //V2.0.6.x 之前默认密码是root |
| zoneId | 设置时区相关的ZoneId | "" |
| fetchSize | 设置查询结果的获取大小 | 10000 |
| database | 设置目标数据库名称 | "" |
示例工程源代码:
example/client-cpp-example/src/TableModelSessionExample.cpp : TableModelSessionExample编译成功后,示例代码工程位于 example/client-cpp-example/target
#include "TableSession.h" #include "TableSessionBuilder.h" using namespace std; TableSession *session; void insertRelationalTablet() { vector<pair<string, TSDataType::TSDataType>> 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<ColumnCategory> 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<SessionDataSet> &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<SessionDataSet> &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("TimechoDB@2021") //V2.0.6.x 之前默认密码是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<SessionDataSet> 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<SessionDataSet> 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<SessionDataSet> 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("TimechoDB@2021") //V2.0.6.x 之前默认密码是root ->database("db1") ->build(); cout << "[Show tables from current database(db1)]\n" << endl; try { unique_ptr<SessionDataSet> 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<SessionDataSet> 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; }
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
Windows:Maven 编译 Thrift 时需要使用 wget 下载远端文件,可能出现以下报错:
Failed to delete cached file C:\Users\Administrator\.m2\repository\.cache\download-maven-plugin\index.ser
解决方法: