C++ Native API
Dependencies
- Java 8+
- Flex
- Bison 2.7+
- Boost 1.56+
- OpenSSL 1.0+
- GCC 4.8.5+
Installation
Install Required Dependencies
-
MAC
-
Install Bison:
Use the following brew command to install the Bison version:
1. brew install bison2. Install Boost: Make sure to install the latest version of Boost.1. brew install boost3. 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:
1. sudo apt-get update
2. 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:
1. sudo yum update
2. sudo yum install gcc gcc-c++ boost-devel bison flex openssl-devel
- Windows
-
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.
-
Download and Install Flex, Bison
-
Download Win_Flex_Bison.
- 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.
-
Install Boost Library
-
Download Boost.
- Compile Boost locally: Run
bootstrap.batandb2.exein sequence. - Add the Boost installation directory to the PATH environment variable, e.g.,
C:\Program Files (x86)\boost_1_78_0. -
Install OpenSSL
-
Download and install OpenSSL.
- Add the include directory under the installation directory to the PATH environment variable.
Compilation
Clone the source code from git:
1. 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):
1. git checkout rc/1.3.2
Run Maven to compile in the IoTDB root directory:
- Mac or Linux with glibc version >= 2.32
1. ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp
- Linux with glibc version >= 2.31
1. ./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.23
1. ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-glibc223-SNAPSHOT
- Linux with glibc version >= 2.17
1. ./mvnw clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp -Diotdb-tools-thrift.version=0.14.1.1-gcc4-SNAPSHOT
- Windows using Visual Studio 2022
1. .\mvnw.cmd clean package -pl example/client-cpp-example -am -DskipTests -P with-cpp
- Windows using Visual Studio 2019
1. .\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.
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-SNAPSHOTor-Diotdb-tools-thrift.version=0.14.1.1-old-glibc-SNAPSHOTto 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".
Native APIs
Here we show the commonly used interfaces and their parameters in the Native API:
Initialization
- Open a Session
1. void open();
- Open a session, with a parameter to specify whether to enable RPC compression
1. void open(bool enableRPCCompression);
Notice: this RPC compression status of client must comply with that of IoTDB server
- Close a Session
1. void close();
Data Definition Interface (DDL)
Database Management
- CREATE DATABASE
1. void setStorageGroup(const std::string &storageGroupId);
- Delete one or several databases
1. void deleteStorageGroup(const std::string &storageGroup);
2. void deleteStorageGroups(const std::vector<std::string> &storageGroups);
Timeseries Management
- Create one or multiple timeseries
1. void createTimeseries(const std::string &path, TSDataType::TSDataType dataType, TSEncoding::TSEncoding encoding,
2. CompressionType::CompressionType compressor);
4. void createMultiTimeseries(const std::vector<std::string> &paths,
5. const std::vector<TSDataType::TSDataType> &dataTypes,
6. const std::vector<TSEncoding::TSEncoding> &encodings,
7. const std::vector<CompressionType::CompressionType> &compressors,
8. std::vector<std::map<std::string, std::string>> *propsList,
9. std::vector<std::map<std::string, std::string>> *tagsList,
10. std::vector<std::map<std::string, std::string>> *attributesList,
11. std::vector<std::string> *measurementAliasList);
- Create aligned timeseries
1. void createAlignedTimeseries(const std::string &deviceId,
2. const std::vector<std::string> &measurements,
3. const std::vector<TSDataType::TSDataType> &dataTypes,
4. const std::vector<TSEncoding::TSEncoding> &encodings,
5. const std::vector<CompressionType::CompressionType> &compressors);
- Delete one or several timeseries
1. void deleteTimeseries(const std::string &path);
2. void deleteTimeseries(const std::vector<std::string> &paths);
- Check whether the specific timeseries exists.
1. bool checkTimeseriesExists(const std::string &path);
Schema Template
- Create a schema template
1. void createSchemaTemplate(const Template &templ);
- Set the schema template named
templateNameat pathprefixPath.
1. void setSchemaTemplate(const std::string &template_name, const std::string &prefix_path);
- Unset the schema template
1. void unsetSchemaTemplate(const std::string &prefix_path, const std::string &template_name);
- After measurement template created, you can edit the template with belowed APIs.
1. // Add aligned measurements to a template
2. void addAlignedMeasurementsInTemplate(const std::string &template_name,
3. const std::vector<std::string> &measurements,
4. const std::vector<TSDataType::TSDataType> &dataTypes,
5. const std::vector<TSEncoding::TSEncoding> &encodings,
6. const std::vector<CompressionType::CompressionType> &compressors);
8. // Add one aligned measurement to a template
9. void addAlignedMeasurementsInTemplate(const std::string &template_name,
10. const std::string &measurement,
11. TSDataType::TSDataType dataType,
12. TSEncoding::TSEncoding encoding,
13. CompressionType::CompressionType compressor);
15. // Add unaligned measurements to a template
16. void addUnalignedMeasurementsInTemplate(const std::string &template_name,
17. const std::vector<std::string> &measurements,
18. const std::vector<TSDataType::TSDataType> &dataTypes,
19. const std::vector<TSEncoding::TSEncoding> &encodings,
20. const std::vector<CompressionType::CompressionType> &compressors);
22. // Add one unaligned measurement to a template
23. void addUnalignedMeasurementsInTemplate(const std::string &template_name,
24. const std::string &measurement,
25. TSDataType::TSDataType dataType,
26. TSEncoding::TSEncoding encoding,
27. CompressionType::CompressionType compressor);
29. // Delete a node in template and its children
30. void deleteNodeInTemplate(const std::string &template_name, const std::string &path);
- You can query measurement templates with these APIS:
1. // Return the amount of measurements inside a template
2. int countMeasurementsInTemplate(const std::string &template_name);
4. // Return true if path points to a measurement, otherwise returne false
5. bool isMeasurementInTemplate(const std::string &template_name, const std::string &path);
7. // Return true if path exists in template, otherwise return false
8. bool isPathExistInTemplate(const std::string &template_name, const std::string &path);
10. // Return all measurements paths inside template
11. std::vector<std::string> showMeasurementsInTemplate(const std::string &template_name);
13. // Return all measurements paths under the designated patter inside template
14. std::vector<std::string> showMeasurementsInTemplate(const std::string &template_name, const std::string &pattern);
Data Manipulation Interface (DML)
Insert
It is recommended to use insertTablet to help improve write efficiency.
- Insert a Tablet,which is multiple rows of a device, each row has the same measurements
- Better Write Performance
- Support null values: fill the null value with any value, and then mark the null value via BitMap
1. void insertTablet(Tablet &tablet);
- Insert multiple Tablets
1. void insertTablets(std::unordered_map<std::string, Tablet *> &tablets);
- Insert a Record, which contains multiple measurement value of a device at a timestamp
1. void insertRecord(const std::string &deviceId, int64_t time, const std::vector<std::string> &measurements,
2. const std::vector<TSDataType::TSDataType> &types, const std::vector<char *> &values);
- Insert multiple Records
1. void insertRecords(const std::vector<std::string> &deviceIds,
2. const std::vector<int64_t> ×,
3. const std::vector<std::vector<std::string>> &measurementsList,
4. const std::vector<std::vector<TSDataType::TSDataType>> &typesList,
5. const std::vector<std::vector<char *>> &valuesList);
- Insert multiple Records that belong to the same device. With type info the server has no need to do type inference, which leads a better performance
1. void insertRecordsOfOneDevice(const std::string &deviceId,
2. std::vector<int64_t> ×,
3. std::vector<std::vector<std::string>> &measurementsList,
4. std::vector<std::vector<TSDataType::TSDataType>> &typesList,
5. std::vector<std::vector<char *>> &valuesList);
Insert with type inference
Without type information, server has to do type inference, which may cost some time.
1. void insertRecord(const std::string &deviceId, int64_t time, const std::vector<std::string> &measurements,
2. const std::vector<std::string> &values);
5. void insertRecords(const std::vector<std::string> &deviceIds,
6. const std::vector<int64_t> ×,
7. const std::vector<std::vector<std::string>> &measurementsList,
8. const std::vector<std::vector<std::string>> &valuesList);
11. void insertRecordsOfOneDevice(const std::string &deviceId,
12. std::vector<int64_t> ×,
13. std::vector<std::vector<std::string>> &measurementsList,
14. const std::vector<std::vector<std::string>> &valuesList);
Insert data into Aligned Timeseries
The Insert of aligned timeseries uses interfaces like insertAlignedXXX, and others are similar to the above interfaces:
- insertAlignedRecord
- insertAlignedRecords
- insertAlignedRecordsOfOneDevice
- insertAlignedTablet
- insertAlignedTablets
Delete
- Delete data in a time range of one or several timeseries
1. void deleteData(const std::string &path, int64_t endTime);
2. void deleteData(const std::vector<std::string> &paths, int64_t endTime);
3. void deleteData(const std::vector<std::string> &paths, int64_t startTime, int64_t endTime);
IoTDB-SQL Interface
- Execute query statement
1. unique_ptr<SessionDataSet> executeQueryStatement(const std::string &sql);
The SessionDataSet class primarily provides the following methods:
| Method Name | Description | Parameters | Return Type |
|---|---|---|---|
| hasNext() | Checks whether there are more rows of data in the result set. | - | bool |
| next() | Retrieves the next row of data from the result set, encapsulated as a RowRecord object. |
- | std::shared_ptr<RowRecord> |
| getIterator() | Obtains a DataIterator iterator for traversing the data in a more flexible manner (e.g., column-by-column). |
- | SessionDataSet::DataIterator |
| getColumnNames() | Retrieves a list of names for all columns in the result set. | - | const std::vector<std::string>& |
| getColumnTypeList() | Retrieves a list of data types for all columns in the result set. | - | const std::vector<tsfile::type::TSDataType>& |
| getFetchSize() | Gets the current number of rows fetched in each batch from the server. | - | int |
| setFetchSize(int fetchSize) | Sets the number of rows to be fetched in each batch from the server. | fetchSize: The number of rows to fetch per batch |
void |
| closeOperationHandle(bool forceClose) | Closes the query handle on the server side and releases resources. It is recommended to call this method after finishing using the dataset. | forceClose: Whether to force close (defaults to false) |
void |
- Execute non query statement
1. void executeNonQueryStatement(const std::string &sql);
Examples
The sample code of using these interfaces is in:
example/client-cpp-example/src/SessionExample.cpp: SessionExampleexample/client-cpp-example/src/AlignedTimeseriesSessionExample.cpp(Aligned Timeseries) : AlignedTimeseriesSessionExample
If the compilation finishes successfully, the example project will be placed under example/client-cpp-example/target
FAQ
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>
on Windows
When Building Thrift and downloading packages via “wget”, a possible annoying issue may occur with error message looks like:
1. 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
<skipCache>true</skipCache>configuration to the download-maven-plugin maven phase that complains this error.
