C++ 原生接口
C++ 原生接口
依賴
- Java 8+
- Flex
- Bison 2.7+
- Boost 1.56+
- OpenSSL 1.0+
- GCC 4.8.5+
安裝
安裝相關(guān)依賴
- MAC
安裝 Bison :
使用下面 brew 命令安裝 bison 版本:
brew install bison安裝 Boost :確保安裝最新的 Boost 版本。
brew install boost檢查 OpenSSL :確保 openssl 庫(kù)已安裝,默認(rèn)的 openssl 頭文件路徑為"/usr/local/opt/openssl/include"
如果在編譯過(guò)程中出現(xiàn)找不到 openssl 的錯(cuò)誤,嘗試添加
-Dopenssl.include.dir=""
Ubuntu 16.04+ 或其他 Debian 系列
使用以下命令安裝所賴:
sudo apt-get update sudo apt-get install gcc g++ bison flex libboost-all-dev libssl-devCentOS 7.7+/Fedora/Rocky Linux 或其他 Red-hat 系列
使用 yum 命令安裝依賴:
sudo yum update sudo yum install gcc gcc-c++ boost-devel bison flex openssl-develWindows
構(gòu)建編譯環(huán)境
- 安裝 MS Visual Studio(推薦安裝 2019+ 版本):安裝時(shí)需要勾選 Visual Studio C/C++ IDE and compiler(supporting CMake, Clang, MinGW)
- 下載安裝 CMake 。
下載安裝 Flex、Bison
- 下載 Win_Flex_Bison
- 下載后需要將可執(zhí)行文件重命名為 flex.exe 和 bison.exe 以保證編譯時(shí)能夠被找到,添加可執(zhí)行文件的目錄到 PATH 環(huán)境變量中
安裝 Boost 庫(kù)
- 下載 Boost
- 本地編譯 Boost :依次執(zhí)行 bootstrap.bat 和 b2.exe
- 添加 Boost 安裝目錄到 PATH 環(huán)境變量中,例如
C:\Program Files (x86)\boost_1_78_0
安裝 OpenSSL
- 下載安裝 OpenSSL
- 添加 OpenSSL 下的 include 目錄到 PATH 環(huán)境變量中
執(zhí)行編譯
從 git 克隆源代碼:
git clone https://github.com/apache/iotdb.git默認(rèn)的主分支是 master 分支,如果你想使用某個(gè)發(fā)布版本,請(qǐng)切換分支 (如 1.3.2 版本):
git checkout rc/1.3.2在 IoTDB 根目錄下執(zhí)行 maven 編譯:
Mac 或 glibc 版本 >= 2.32 的 Linux
./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cppglibc 版本 >= 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-SNAPSHOTglibc 版本 >= 2.23 的 Linux
./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-glibc223-SNAPSHOTglibc 版本 >= 2.17 的 Linux
./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-gcc4-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- 如果沒(méi)有將 Boost 庫(kù)地址加入 PATH 環(huán)境變量,在編譯命令中還需添加相關(guān)參數(shù),例如:
-DboostIncludeDir="C:\Program Files (x86)\boost_1_78_0" -DboostLibraryDir="C:\Program Files (x86)\boost_1_78_0\stage\lib"
- 如果沒(méi)有將 Boost 庫(kù)地址加入 PATH 環(huán)境變量,在編譯命令中還需添加相關(guān)參數(shù),例如:
編譯成功后,打包好的庫(kù)文件位于 iotdb-client/client-cpp/target 中,同時(shí)可以在 example/client-cpp-example/target 下找到編譯好的示例程序。
編譯 Q&A
Q:Linux 上的環(huán)境有哪些要求呢?
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 這里的代碼
- 執(zhí)行
./mvnw clean install - 回到 iotdb 代碼目錄執(zhí)行
./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp
Q:Linux 編譯報(bào)錯(cuò)undefined reference to '_libc_sinle_thread'如何處理?
A:
- 該問(wèn)題是用于默認(rèn)的預(yù)編譯 Thrift 依賴了過(guò)高的 glibc 版本導(dǎo)致的
- 可以嘗試在編譯的 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 或更早版本進(jìn)行編譯,要怎么做?
A:
- 可以嘗試自己本地編譯 Thrift 后再進(jìn)行客戶端的編譯
- 下載 https://github.com/apache/iotdb-bin-resources/tree/iotdb-tools-thrift-v0.14.1.0/iotdb-tools-thrift 這里的代碼
- 執(zhí)行
.\mvnw.cmd clean install - 回到 iotdb 代碼目錄執(zhí)行
.\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Dcmake.generator="Visual Studio 15 2017"
基本接口說(shuō)明
下面將給出 Session 接口的簡(jiǎn)要介紹和原型定義:
初始化
- 開(kāi)啟 Session
void open();- 開(kāi)啟 Session,并決定是否開(kāi)啟 RPC 壓縮
void open(bool enableRPCCompression);注意: 客戶端的 RPC 壓縮開(kāi)啟狀態(tài)需和服務(wù)端一致。
- 關(guān)閉 Session
void close();數(shù)據(jù)定義接口(DDL)
Database 管理
- 設(shè)置 database
void setStorageGroup(const std::string &storageGroupId);- 刪除單個(gè)或多個(gè) database
void deleteStorageGroup(const std::string &storageGroup);
void deleteStorageGroups(const std::vector<std::string> &storageGroups);時(shí)間序列管理
- 創(chuàng)建單個(gè)或多個(gè)非對(duì)齊時(shí)間序列
void createTimeseries(const std::string &path, TSDataType::TSDataType dataType, TSEncoding::TSEncoding encoding,
CompressionType::CompressionType compressor);
void createMultiTimeseries(const std::vector<std::string> &paths,
const std::vector<TSDataType::TSDataType> &dataTypes,
const std::vector<TSEncoding::TSEncoding> &encodings,
const std::vector<CompressionType::CompressionType> &compressors,
std::vector<std::map<std::string, std::string>> *propsList,
std::vector<std::map<std::string, std::string>> *tagsList,
std::vector<std::map<std::string, std::string>> *attributesList,
std::vector<std::string> *measurementAliasList);- 創(chuàng)建對(duì)齊時(shí)間序列
void createAlignedTimeseries(const std::string &deviceId,
const std::vector<std::string> &measurements,
const std::vector<TSDataType::TSDataType> &dataTypes,
const std::vector<TSEncoding::TSEncoding> &encodings,
const std::vector<CompressionType::CompressionType> &compressors);- 刪除一個(gè)或多個(gè)時(shí)間序列
void deleteTimeseries(const std::string &path);
void deleteTimeseries(const std::vector<std::string> &paths);- 檢查時(shí)間序列是否存在
bool checkTimeseriesExists(const std::string &path);元數(shù)據(jù)模版
- 創(chuàng)建元數(shù)據(jù)模板
void createSchemaTemplate(const Template &templ);- 掛載元數(shù)據(jù)模板
void setSchemaTemplate(const std::string &template_name, const std::string &prefix_path);請(qǐng)注意,如果一個(gè)子樹(shù)中有多個(gè)孩子節(jié)點(diǎn)需要使用模板,可以在其共同父母節(jié)點(diǎn)上使用 setSchemaTemplate 。而只有在已有數(shù)據(jù)點(diǎn)插入模板對(duì)應(yīng)的物理量時(shí),模板才會(huì)被設(shè)置為激活狀態(tài),進(jìn)而被 show timeseries 等查詢檢測(cè)到。
- 卸載元數(shù)據(jù)模板
void unsetSchemaTemplate(const std::string &prefix_path, const std::string &template_name);注意:目前不支持從曾經(jīng)在prefixPath路徑及其后代節(jié)點(diǎn)使用模板插入數(shù)據(jù)后(即使數(shù)據(jù)已被刪除)卸載模板。
- 在創(chuàng)建概念元數(shù)據(jù)模板以后,還可以通過(guò)以下接口增加或刪除模板內(nèi)的物理量。請(qǐng)注意,已經(jīng)掛載的模板不能刪除內(nèi)部的物理量。
// 為指定模板新增一組對(duì)齊的物理量,若其父節(jié)點(diǎn)在模板中已經(jīng)存在,且不要求對(duì)齊,則報(bào)錯(cuò)
void addAlignedMeasurementsInTemplate(const std::string &template_name,
const std::vector<std::string> &measurements,
const std::vector<TSDataType::TSDataType> &dataTypes,
const std::vector<TSEncoding::TSEncoding> &encodings,
const std::vector<CompressionType::CompressionType> &compressors);
// 為指定模板新增一個(gè)對(duì)齊物理量, 若其父節(jié)點(diǎn)在模板中已經(jīng)存在,且不要求對(duì)齊,則報(bào)錯(cuò)
void addAlignedMeasurementsInTemplate(const std::string &template_name,
const std::string &measurement,
TSDataType::TSDataType dataType,
TSEncoding::TSEncoding encoding,
CompressionType::CompressionType compressor);
// 為指定模板新增一個(gè)不對(duì)齊物理量, 若其父節(jié)在模板中已經(jīng)存在,且要求對(duì)齊,則報(bào)錯(cuò)
void addUnalignedMeasurementsInTemplate(const std::string &template_name,
const std::vector<std::string> &measurements,
const std::vector<TSDataType::TSDataType> &dataTypes,
const std::vector<TSEncoding::TSEncoding> &encodings,
const std::vector<CompressionType::CompressionType> &compressors);
// 為指定模板新增一組不對(duì)齊的物理量, 若其父節(jié)在模板中已經(jīng)存在,且要求對(duì)齊,則報(bào)錯(cuò)
void addUnalignedMeasurementsInTemplate(const std::string &template_name,
const std::string &measurement,
TSDataType::TSDataType dataType,
TSEncoding::TSEncoding encoding,
CompressionType::CompressionType compressor);
// 從指定模板中刪除一個(gè)節(jié)點(diǎn)及其子樹(shù)
void deleteNodeInTemplate(const std::string &template_name, const std::string &path);- 對(duì)于已經(jīng)創(chuàng)建的元數(shù)據(jù)模板,還可以通過(guò)以下接口查詢模板信息:
// 查詢返回目前模板中所有物理量的數(shù)量
int countMeasurementsInTemplate(const std::string &template_name);
// 檢查模板內(nèi)指定路徑是否為物理量
bool isMeasurementInTemplate(const std::string &template_name, const std::string &path);
// 檢查在指定模板內(nèi)是否存在某路徑
bool isPathExistInTemplate(const std::string &template_name, const std::string &path);
// 返回指定模板內(nèi)所有物理量的路徑
std::vector<std::string> showMeasurementsInTemplate(const std::string &template_name);
// 返回指定模板內(nèi)某前綴路徑下的所有物理量的路徑
std::vector<std::string> showMeasurementsInTemplate(const std::string &template_name, const std::string &pattern);數(shù)據(jù)操作接口(DML)
數(shù)據(jù)寫入
推薦使用 insertTablet 幫助提高寫入效率。
- 插入一個(gè) Tablet,Tablet 是一個(gè)設(shè)備若干行數(shù)據(jù)塊,每一行的列都相同。
- 寫入效率高。
- 支持寫入空值:空值處可以填入任意值,然后通過(guò) BitMap 標(biāo)記空值。
void insertTablet(Tablet &tablet);- 插入多個(gè) Tablet
void insertTablets(std::unordered_map<std::string, Tablet *> &tablets);- 插入一個(gè) Record,一個(gè) Record 是一個(gè)設(shè)備一個(gè)時(shí)間戳下多個(gè)測(cè)點(diǎn)的數(shù)據(jù)
void insertRecord(const std::string &deviceId, int64_t time, const std::vector<std::string> &measurements,
const std::vector<TSDataType::TSDataType> &types, const std::vector<char *> &values);- 插入多個(gè) Record
void insertRecords(const std::vector<std::string> &deviceIds,
const std::vector<int64_t> ×,
const std::vector<std::vector<std::string>> &measurementsList,
const std::vector<std::vector<TSDataType::TSDataType>> &typesList,
const std::vector<std::vector<char *>> &valuesList);- 插入同屬于一個(gè) device 的多個(gè) Record
void insertRecordsOfOneDevice(const std::string &deviceId,
std::vector<int64_t> ×,
std::vector<std::vector<std::string>> &measurementsList,
std::vector<std::vector<TSDataType::TSDataType>> &typesList,
std::vector<std::vector<char *>> &valuesList);帶有類型推斷的寫入
服務(wù)器需要做類型推斷,可能會(huì)有額外耗時(shí),速度較無(wú)需類型推斷的寫入慢。
void insertRecord(const std::string &deviceId, int64_t time, const std::vector<std::string> &measurements,
const std::vector<std::string> &values);
void insertRecords(const std::vector<std::string> &deviceIds,
const std::vector<int64_t> ×,
const std::vector<std::vector<std::string>> &measurementsList,
const std::vector<std::vector<std::string>> &valuesList);
void insertRecordsOfOneDevice(const std::string &deviceId,
std::vector<int64_t> ×,
std::vector<std::vector<std::string>> &measurementsList,
const std::vector<std::vector<std::string>> &valuesList);對(duì)齊時(shí)間序列寫入
對(duì)齊時(shí)間序列的寫入使用 insertAlignedXXX 接口,其余與上述接口類似:
- insertAlignedRecord
- insertAlignedRecords
- insertAlignedRecordsOfOneDevice
- insertAlignedTablet
- insertAlignedTablets
數(shù)據(jù)刪除
- 刪除一個(gè)或多個(gè)時(shí)間序列在某個(gè)時(shí)間范圍的數(shù)據(jù)
void deleteData(const std::string &path, int64_t endTime);
void deleteData(const std::vector<std::string> &paths, int64_t endTime);
void deleteData(const std::vector<std::string> &paths, int64_t startTime, int64_t endTime);IoTDB-SQL 接口
- 執(zhí)行查詢語(yǔ)句
unique_ptr<SessionDataSet> executeQueryStatement(const std::string &sql);返回值 SessionDataSet 類主要提供如下方法:
| 方法名 | 描述 | 參數(shù) | 返回值 |
|---|---|---|---|
| hasNext() | 判斷結(jié)果集中是否還有更多數(shù)據(jù)行。 | - | bool |
| next() | 獲取結(jié)果集中的下一行數(shù)據(jù),封裝為一個(gè) RowRecord 對(duì)象。 | - | std::shared_ptr |
| getIterator() | 獲取一個(gè) DataIterator 迭代器,用于以更靈活的方式(按列)遍歷數(shù)據(jù)。 | - | SessionDataSet::DataIterator |
| getColumnNames() | 獲取結(jié)果集中所有列的名稱列表。 | - | const std::vector& |
| getColumnTypeList() | 獲取結(jié)果集中所有列的數(shù)據(jù)類型列表。 | - | const std::vector& |
| getFetchSize() | 獲取當(dāng)前每次從服務(wù)器批量抓取數(shù)據(jù)的行數(shù)。 | - | int |
| setFetchSize(int fetchSize) | 設(shè)置每次從服務(wù)器批量抓取數(shù)據(jù)的行數(shù)。 | fetchSize: 批量抓取數(shù)據(jù)的行數(shù) | void |
| closeOperationHandle(bool forceClose) | 關(guān)閉服務(wù)器端的查詢句柄,釋放資源。建議在數(shù)據(jù)集使用完畢后調(diào)用。 | forceClose: 是否強(qiáng)制關(guān)閉(默認(rèn)為 false) | void |
- 執(zhí)行非查詢語(yǔ)句
void executeNonQueryStatement(const std::string &sql);示例代碼
示例工程源代碼:
example/client-cpp-example/src/SessionExample.cpp: SessionExampleexample/client-cpp-example/src/AlignedTimeseriesSessionExample.cpp(使用對(duì)齊時(shí)間序列): AlignedTimeseriesSessionExample
編譯成功后,示例代碼工程位于 example/client-cpp-example/target
FAQ
Thrift 編譯相關(guān)問(wèn)題
MAC:本地 Maven 編譯 Thrift 時(shí)如出現(xiàn)以下鏈接的問(wèn)題,可以嘗試將 xcode-commandline 版本從 12 降低到 11.5
https://stackoverflow.com/questions/63592445/ld-unsupported-tapi-file-type-tapi-tbd-in-yaml-file/65518087#65518087Windows:Maven 編譯 Thrift 時(shí)需要使用 wget 下載遠(yuǎn)端文件,可能出現(xiàn)以下報(bào)錯(cuò):
Failed to delete cached file C:\Users\Administrator\.m2\repository\.cache\download-maven-plugin\index.ser解決方法:
- 嘗試刪除 ".m2\repository\.cache" 目錄并重試。
- 在添加 pom 文件對(duì)應(yīng)的 download-maven-plugin 中添加 "<skipCache>true</skipCache>"