diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000000000..1d96b4dda856a
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,32 @@
+# 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.
+
+---
+BasedOnStyle: LLVM
+IndentWidth: 2
+TabWidth: 2
+UseTab: Never
+ColumnLimit: 100
+BreakBeforeBraces: Attach
+AllowShortIfStatementsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Empty
+PointerAlignment: Left
+DerivePointerAlignment: false
+SortIncludes: false
+ReflowComments: false
+Standard: c++11
+...
diff --git a/.github/workflows/client-cpp-package.yml b/.github/workflows/client-cpp-package.yml
index c6412b001e7f5..b403dfad9dd41 100644
--- a/.github/workflows/client-cpp-package.yml
+++ b/.github/workflows/client-cpp-package.yml
@@ -87,7 +87,20 @@ jobs:
run: |
set -euxo pipefail
sudo apt-get update
- sudo apt-get install -y libboost-all-dev openssl libssl-dev
+ sudo apt-get install -y libboost-all-dev openssl libssl-dev wget
+ . /etc/os-release
+ if [[ "${VERSION_CODENAME}" == "jammy" ]]; then
+ wget -qO /tmp/llvm.sh https://apt.llvm.org/llvm.sh
+ chmod +x /tmp/llvm.sh
+ sudo DEBIAN_FRONTEND=noninteractive /tmp/llvm.sh 17
+ # llvm.sh installs clang-17/lldb/lld/clangd but not the clang-format-17 package
+ sudo apt-get install -y clang-format-17
+ else
+ sudo apt-get install -y clang-format-17
+ fi
+ sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-17 100
+ sudo update-alternatives --set clang-format /usr/bin/clang-format-17
+ clang-format --version
- name: Cache Maven packages
uses: actions/cache@v5
with:
@@ -99,9 +112,7 @@ jobs:
shell: bash
run: |
set -euxo pipefail
- ./mvnw clean package -P with-cpp -pl iotdb-client/client-cpp -am \
- -DskipTests \
- -Dspotless.check.skip=true -Dspotless.apply.skip=true
+ ./mvnw clean package -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests
- name: Upload zip artifact
uses: actions/upload-artifact@v6
with:
@@ -133,7 +144,10 @@ jobs:
shell: bash
run: |
set -euxo pipefail
- brew install boost openssl
+ brew install boost openssl llvm@17
+ ln -sf "$(brew --prefix llvm@17)/bin/clang-format" "$(brew --prefix)/bin/clang-format"
+ echo "$(brew --prefix llvm@17)/bin" >> "$GITHUB_PATH"
+ clang-format --version
- name: Cache Maven packages
uses: actions/cache@v5
with:
@@ -147,9 +161,7 @@ jobs:
MACOSX_DEPLOYMENT_TARGET: "12.0"
run: |
set -euxo pipefail
- ./mvnw clean package -P with-cpp -pl iotdb-client/client-cpp -am \
- -DskipTests \
- -Dspotless.check.skip=true -Dspotless.apply.skip=true
+ ./mvnw clean package -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests
- name: Upload zip artifact
uses: actions/upload-artifact@v6
with:
@@ -194,6 +206,8 @@ jobs:
$sslPath = (Get-ChildItem 'C:\Program Files\OpenSSL*' -Directory | Select-Object -First 1).FullName
echo "$sslPath\bin" >> $env:GITHUB_PATH
echo "OPENSSL_ROOT_DIR=$sslPath" >> $env:GITHUB_ENV
+ choco install llvm --version=17.0.6 --force -y
+ clang-format --version
- name: Cache Maven packages
uses: actions/cache@v5
with:
@@ -208,9 +222,7 @@ jobs:
IOTDB_TOOLS_THRIFT_VERSION: ${{ matrix.iotdb_tools_thrift_version }}
run: |
set -euxo pipefail
- MVN_ARGS=(./mvnw clean package -P with-cpp -pl iotdb-client/client-cpp -am \
- -DskipTests \
- -Dspotless.check.skip=true -Dspotless.apply.skip=true)
+ MVN_ARGS=(./mvnw clean package -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests)
if [ -n "${CMAKE_GENERATOR:-}" ]; then
MVN_ARGS+=("-Dcmake.generator=${CMAKE_GENERATOR}")
fi
diff --git a/.github/workflows/multi-language-client.yml b/.github/workflows/multi-language-client.yml
index 831e3e37639b6..c2abe1a718f32 100644
--- a/.github/workflows/multi-language-client.yml
+++ b/.github/workflows/multi-language-client.yml
@@ -54,16 +54,33 @@ jobs:
if: runner.os == 'Linux'
shell: bash
run: |
+ set -euxo pipefail
sudo apt-get update
- sudo apt-get install libboost-all-dev
- sudo apt-get install openssl libssl-dev
+ sudo apt-get install -y libboost-all-dev openssl libssl-dev wget
+ # jammy (22.04): no clang-format-17 in default repos — use apt.llvm.org (same LLVM 17 as noble/choco/brew)
+ . /etc/os-release
+ if [[ "${VERSION_CODENAME}" == "jammy" ]]; then
+ wget -qO /tmp/llvm.sh https://apt.llvm.org/llvm.sh
+ chmod +x /tmp/llvm.sh
+ sudo DEBIAN_FRONTEND=noninteractive /tmp/llvm.sh 17
+ # llvm.sh installs clang-17/lldb/lld/clangd but not the clang-format-17 package
+ sudo apt-get install -y clang-format-17
+ else
+ sudo apt-get install -y clang-format-17
+ fi
+ sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-17 100
+ sudo update-alternatives --set clang-format /usr/bin/clang-format-17
+ clang-format --version
- name: Install CPP Dependencies (Mac)
# remove some xcode to release disk space
if: runner.os == 'macOS'
shell: bash
run: |
brew install boost
- brew install openssl
+ brew install openssl llvm@17
+ ln -sf "$(brew --prefix llvm@17)/bin/clang-format" "$(brew --prefix)/bin/clang-format"
+ echo "$(brew --prefix llvm@17)/bin" >> "$GITHUB_PATH"
+ clang-format --version
sudo rm -rf /Applications/Xcode_14.3.1.app
sudo rm -rf /Applications/Xcode_15.0.1.app
sudo rm -rf /Applications/Xcode_15.1.app
@@ -72,21 +89,28 @@ jobs:
- name: Install CPP Dependencies (Windows)
if: runner.os == 'Windows'
run: |
- choco install winflexbison3
- choco install boost-msvc-14.3
+ choco install winflexbison3 -y
+ choco install boost-msvc-14.3 -y
$boost_path = (Get-ChildItem -Path 'C:\local\' -Filter 'boost_*').FullName
echo $boost_path >> $env:GITHUB_PATH
- choco install openssl
+ choco install openssl -y
$sslPath = (Get-ChildItem 'C:\Program Files\OpenSSL*' -Directory | Select-Object -First 1).FullName
echo "$sslPath\bin" >> $env:GITHUB_PATH
echo "OPENSSL_ROOT_DIR=$sslPath" >> $env:GITHUB_ENV
+ choco install llvm --version=17.0.6 --force -y
+ clang-format --version
- name: Cache Maven packages
uses: actions/cache@v5
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2-
+ - name: Check C++ format (Spotless)
+ shell: bash
+ run: |
+ ./mvnw -P with-cpp -pl iotdb-client/client-cpp spotless:check
+ ./mvnw -P with-cpp -pl example/client-cpp-example spotless:check
- name: Build IoTDB server
shell: bash
run: ./mvnw clean install -pl distribution -am -DskipTests
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a80f5284aad76..ca0f57325058a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -107,6 +107,31 @@ plugin](https://github.com/diffplug/spotless/tree/main/plugin-maven) together wi
import static all other imports
```
+### C++ formatting
+
+- Formatter: `clang-format` only
+- Version: pinned as `clang.format.version` in the root `pom.xml` (currently `17.0.6`, aligned with Apache TsFile); CI installs LLVM/clang-format so the default `clang-format` on the runner matches that version
+- Entrypoint: Maven Spotless; the `clangFormat` configuration is attached under the `spotless-cpp` profile in the C++ modules and activates only on **JDK 11+**, so run `spotless:check` / `spotless:apply` for C++ with JDK 11 or newer (CI does). JDK 8 builds elsewhere in the reactor do not load that Spotless fragment.
+
+Check only:
+
+`./mvnw -P with-cpp -pl iotdb-client/client-cpp spotless:check`
+
+`./mvnw -P with-cpp -pl example/client-cpp-example spotless:check`
+
+Auto-fix:
+
+`./mvnw -P with-cpp -pl iotdb-client/client-cpp spotless:apply`
+
+`./mvnw -P with-cpp -pl example/client-cpp-example spotless:apply`
+
+On Windows PowerShell, a comma inside `-pl` can be parsed incorrectly; use the two commands above, or quote the full `-pl` value, for example `./mvnw -P with-cpp "-pl=iotdb-client/client-cpp,example/client-cpp-example" spotless:check`.
+
+Temporarily skip Spotless (not recommended except emergency CI triage):
+
+`-Dspotless.skip=true`
+
+Risk: skipping formatting checks can introduce style drift between contributors and CI, and often causes follow-up format-only commits.
## Contributing code
diff --git a/example/client-cpp-example/pom.xml b/example/client-cpp-example/pom.xml
index d7df404dcde69..9668aee28ebdf 100644
--- a/example/client-cpp-example/pom.xml
+++ b/example/client-cpp-example/pom.xml
@@ -162,4 +162,39 @@
+
+
+ spotless-cpp
+
+ [11,)
+
+
+
+
+ com.diffplug.spotless
+ spotless-maven-plugin
+ 2.44.5
+
+
+
+ src/**/*.h
+ src/**/*.hpp
+ src/**/*.c
+ src/**/*.cc
+ src/**/*.cpp
+
+
+ src/test/catch2/**
+
+
+ ${clang.format.version}
+
+
+
+
+
+
+
+
+
diff --git a/example/client-cpp-example/src/AlignedTimeseriesSessionExample.cpp b/example/client-cpp-example/src/AlignedTimeseriesSessionExample.cpp
index 2cc04ab3b3946..3675525301ac9 100644
--- a/example/client-cpp-example/src/AlignedTimeseriesSessionExample.cpp
+++ b/example/client-cpp-example/src/AlignedTimeseriesSessionExample.cpp
@@ -21,393 +21,396 @@
using namespace std;
-Session *session;
+Session* session;
#define DEFAULT_ROW_NUMBER 1000000
void createAlignedTimeseries() {
- string alignedDeviceId = "root.sg1.d1";
- vector measurements = {"s1", "s2", "s3"};
- vector alignedTimeseries = {"root.sg1.d1.s1", "root.sg1.d1.s2", "root.sg1.d1.s3"};
- vector dataTypes = {TSDataType::INT32, TSDataType::DOUBLE, TSDataType::BOOLEAN};
- vector encodings = {TSEncoding::PLAIN, TSEncoding::GORILLA, TSEncoding::RLE};
- vector compressors = {
- CompressionType::SNAPPY, CompressionType::UNCOMPRESSED, CompressionType::SNAPPY};
- for (const string ×eries: alignedTimeseries) {
- if (session->checkTimeseriesExists(timeseries)) {
- session->deleteTimeseries(timeseries);
- }
+ string alignedDeviceId = "root.sg1.d1";
+ vector measurements = {"s1", "s2", "s3"};
+ vector alignedTimeseries = {"root.sg1.d1.s1", "root.sg1.d1.s2", "root.sg1.d1.s3"};
+ vector dataTypes = {TSDataType::INT32, TSDataType::DOUBLE,
+ TSDataType::BOOLEAN};
+ vector encodings = {TSEncoding::PLAIN, TSEncoding::GORILLA,
+ TSEncoding::RLE};
+ vector compressors = {
+ CompressionType::SNAPPY, CompressionType::UNCOMPRESSED, CompressionType::SNAPPY};
+ for (const string& timeseries : alignedTimeseries) {
+ if (session->checkTimeseriesExists(timeseries)) {
+ session->deleteTimeseries(timeseries);
}
- session->createAlignedTimeseries(alignedDeviceId, measurements, dataTypes, encodings, compressors);
+ }
+ session->createAlignedTimeseries(alignedDeviceId, measurements, dataTypes, encodings,
+ compressors);
}
void createSchemaTemplate() {
- if (!session->checkTemplateExists("template1")) {
- Template temp("template1", false);
+ if (!session->checkTemplateExists("template1")) {
+ Template temp("template1", false);
- InternalNode iNodeD99("d99", true);
+ InternalNode iNodeD99("d99", true);
- MeasurementNode mNodeS1("s1", TSDataType::INT32, TSEncoding::RLE, CompressionType::SNAPPY);
- MeasurementNode mNodeS2("s2", TSDataType::INT64, TSEncoding::RLE, CompressionType::SNAPPY);
- MeasurementNode mNodeD99S1("s1", TSDataType::DOUBLE, TSEncoding::RLE, CompressionType::SNAPPY);
- MeasurementNode mNodeD99S2("s2", TSDataType::BOOLEAN, TSEncoding::RLE, CompressionType::SNAPPY);
+ MeasurementNode mNodeS1("s1", TSDataType::INT32, TSEncoding::RLE, CompressionType::SNAPPY);
+ MeasurementNode mNodeS2("s2", TSDataType::INT64, TSEncoding::RLE, CompressionType::SNAPPY);
+ MeasurementNode mNodeD99S1("s1", TSDataType::DOUBLE, TSEncoding::RLE, CompressionType::SNAPPY);
+ MeasurementNode mNodeD99S2("s2", TSDataType::BOOLEAN, TSEncoding::RLE, CompressionType::SNAPPY);
- iNodeD99.addChild(mNodeD99S1);
- iNodeD99.addChild(mNodeD99S2);
+ iNodeD99.addChild(mNodeD99S1);
+ iNodeD99.addChild(mNodeD99S2);
- temp.addToTemplate(iNodeD99);
- temp.addToTemplate(mNodeS1);
- temp.addToTemplate(mNodeS2);
+ temp.addToTemplate(iNodeD99);
+ temp.addToTemplate(mNodeS1);
+ temp.addToTemplate(mNodeS2);
- session->createSchemaTemplate(temp);
- session->setSchemaTemplate("template1", "root.sg3.d1");
- }
+ session->createSchemaTemplate(temp);
+ session->setSchemaTemplate("template1", "root.sg3.d1");
+ }
}
void ActivateTemplate() {
- session->executeNonQueryStatement("insert into root.sg3.d1(timestamp,s1, s2) values(200, 1, 1);");
+ session->executeNonQueryStatement("insert into root.sg3.d1(timestamp,s1, s2) values(200, 1, 1);");
}
void showDevices() {
- unique_ptr dataSet = session->executeQueryStatement("show devices with database");
- for (const string &name: dataSet->getColumnNames()) {
- cout << name << " ";
- }
- cout << endl;
-
- dataSet->setFetchSize(1024);
- while (dataSet->hasNext()) {
- cout << dataSet->next()->toString();
- }
- cout << endl;
-
- dataSet->closeOperationHandle();
+ unique_ptr dataSet = session->executeQueryStatement("show devices with database");
+ for (const string& name : dataSet->getColumnNames()) {
+ cout << name << " ";
+ }
+ cout << endl;
+
+ dataSet->setFetchSize(1024);
+ while (dataSet->hasNext()) {
+ cout << dataSet->next()->toString();
+ }
+ cout << endl;
+
+ dataSet->closeOperationHandle();
}
void showTimeseries() {
- unique_ptr dataSet = session->executeQueryStatement("show timeseries");
- for (const string &name: dataSet->getColumnNames()) {
- cout << name << " ";
- }
- cout << endl;
-
- dataSet->setFetchSize(1024);
- while (dataSet->hasNext()) {
- cout << dataSet->next()->toString();
- }
- cout << endl;
-
- dataSet->closeOperationHandle();
+ unique_ptr dataSet = session->executeQueryStatement("show timeseries");
+ for (const string& name : dataSet->getColumnNames()) {
+ cout << name << " ";
+ }
+ cout << endl;
+
+ dataSet->setFetchSize(1024);
+ while (dataSet->hasNext()) {
+ cout << dataSet->next()->toString();
+ }
+ cout << endl;
+
+ dataSet->closeOperationHandle();
}
void insertAlignedRecord() {
- string deviceId = "root.sg1.d1";
- vector measurements;
- measurements.emplace_back("s1");
- measurements.emplace_back("s2");
- measurements.emplace_back("s3");
-
- for (int64_t time = 0; time < 10; time++) {
- vector values;
- values.emplace_back("1");
- values.emplace_back("1.0");
- values.emplace_back("true");
- session->insertAlignedRecord(deviceId, time, measurements, values);
- }
+ string deviceId = "root.sg1.d1";
+ vector measurements;
+ measurements.emplace_back("s1");
+ measurements.emplace_back("s2");
+ measurements.emplace_back("s3");
+
+ for (int64_t time = 0; time < 10; time++) {
+ vector values;
+ values.emplace_back("1");
+ values.emplace_back("1.0");
+ values.emplace_back("true");
+ session->insertAlignedRecord(deviceId, time, measurements, values);
+ }
}
void insertAlignedRecords() {
- string deviceId = "root.sg1.d1";
- vector measurements;
- measurements.emplace_back("s1");
- measurements.emplace_back("s2");
- measurements.emplace_back("s3");
-
- vector deviceIds;
- vector> measurementsList;
- vector> valuesList;
- vector timestamps;
-
- for (int64_t time = 10; time < 20; time++) {
- vector values;
- values.emplace_back("1");
- values.emplace_back("1.0");
- values.emplace_back("true");
-
- deviceIds.push_back(deviceId);
- measurementsList.push_back(measurements);
- valuesList.push_back(values);
- timestamps.push_back(time);
- if (time != 10 && time % 10 == 0) {
- session->insertAlignedRecords(deviceIds, timestamps, measurementsList, valuesList);
- deviceIds.clear();
- measurementsList.clear();
- valuesList.clear();
- timestamps.clear();
- }
+ string deviceId = "root.sg1.d1";
+ vector measurements;
+ measurements.emplace_back("s1");
+ measurements.emplace_back("s2");
+ measurements.emplace_back("s3");
+
+ vector deviceIds;
+ vector> measurementsList;
+ vector> valuesList;
+ vector timestamps;
+
+ for (int64_t time = 10; time < 20; time++) {
+ vector values;
+ values.emplace_back("1");
+ values.emplace_back("1.0");
+ values.emplace_back("true");
+
+ deviceIds.push_back(deviceId);
+ measurementsList.push_back(measurements);
+ valuesList.push_back(values);
+ timestamps.push_back(time);
+ if (time != 10 && time % 10 == 0) {
+ session->insertAlignedRecords(deviceIds, timestamps, measurementsList, valuesList);
+ deviceIds.clear();
+ measurementsList.clear();
+ valuesList.clear();
+ timestamps.clear();
}
+ }
- session->insertAlignedRecords(deviceIds, timestamps, measurementsList, valuesList);
+ session->insertAlignedRecords(deviceIds, timestamps, measurementsList, valuesList);
}
void insertAlignedTablet() {
- pair pairA("s1", TSDataType::INT32);
- pair pairB("s2", TSDataType::DOUBLE);
- pair pairC("s3", TSDataType::DOUBLE);
- vector> schemas;
- schemas.push_back(pairA);
- schemas.push_back(pairB);
- schemas.push_back(pairC);
-
- Tablet tablet("root.sg2.d2", schemas, 100000);
- tablet.setAligned(true);
-
- for (int64_t time = 0; time < DEFAULT_ROW_NUMBER; time++) {
- size_t row = tablet.rowSize++;
- tablet.timestamps[row] = time;
- int randVal1 = 123456;
- double randVal2 = 123456.1234;
- double randVal3 = 123456.1234;
- tablet.addValue(0, row, randVal1);
- tablet.addValue(1, row, randVal2);
- tablet.addValue(2, row, randVal3);
- if (tablet.rowSize == tablet.maxRowNumber) {
- session->insertTablet(tablet, true);
- tablet.reset();
- }
+ pair pairA("s1", TSDataType::INT32);
+ pair pairB("s2", TSDataType::DOUBLE);
+ pair pairC("s3", TSDataType::DOUBLE);
+ vector> schemas;
+ schemas.push_back(pairA);
+ schemas.push_back(pairB);
+ schemas.push_back(pairC);
+
+ Tablet tablet("root.sg2.d2", schemas, 100000);
+ tablet.setAligned(true);
+
+ for (int64_t time = 0; time < DEFAULT_ROW_NUMBER; time++) {
+ size_t row = tablet.rowSize++;
+ tablet.timestamps[row] = time;
+ int randVal1 = 123456;
+ double randVal2 = 123456.1234;
+ double randVal3 = 123456.1234;
+ tablet.addValue(0, row, randVal1);
+ tablet.addValue(1, row, randVal2);
+ tablet.addValue(2, row, randVal3);
+ if (tablet.rowSize == tablet.maxRowNumber) {
+ session->insertTablet(tablet, true);
+ tablet.reset();
}
+ }
- if (tablet.rowSize != 0) {
- session->insertTablet(tablet);
- tablet.reset();
- }
+ if (tablet.rowSize != 0) {
+ session->insertTablet(tablet);
+ tablet.reset();
+ }
}
void insertAlignedTablets() {
- pair pairA("s1", TSDataType::INT32);
- pair pairB("s2", TSDataType::DOUBLE);
- pair pairC("s3", TSDataType::BOOLEAN);
- vector> schemas;
- schemas.push_back(pairA);
- schemas.push_back(pairB);
- schemas.push_back(pairC);
-
- Tablet tablet1("root.sg1.d1", schemas, 100);
- Tablet tablet2("root.sg1.d2", schemas, 100);
- Tablet tablet3("root.sg1.d3", schemas, 100);
-
- unordered_map tabletMap;
- tabletMap["root.sg1.d1"] = &tablet1;
- tabletMap["root.sg1.d2"] = &tablet2;
- tabletMap["root.sg1.d3"] = &tablet3;
-
- for (int64_t time = 0; time < 20; time++) {
- size_t row1 = tablet1.rowSize++;
- size_t row2 = tablet2.rowSize++;
- size_t row3 = tablet3.rowSize++;
- tablet1.timestamps[row1] = time;
- tablet2.timestamps[row2] = time;
- tablet3.timestamps[row3] = time;
-
- int randVal11 = rand();
- int randVal12 = rand();
- int randVal13 = rand();
- tablet1.addValue(0, row1, randVal11);
- tablet2.addValue(0, row2, randVal12);
- tablet3.addValue(0, row3, randVal13);
-
- double randVal21 = rand() / 99.9;
- double randVal22 = rand() / 99.9;
- double randVal23 = rand() / 99.9;
- tablet1.addValue(1, row1, randVal21);
- tablet2.addValue(1, row2, randVal22);
- tablet3.addValue(1, row3, randVal23);
-
- bool randVal31 = (bool)(rand() % 2);
- bool randVal32 = (bool)(rand() % 2);
- bool randVal33 = (bool)(rand() % 2);
- tablet1.addValue(2, row1, randVal31);
- tablet2.addValue(2, row2, randVal32);
- tablet3.addValue(2, row3, randVal33);
-
- if (tablet1.rowSize == tablet1.maxRowNumber) {
- session->insertAlignedTablets(tabletMap, true);
-
- tablet1.reset();
- tablet2.reset();
- tablet3.reset();
- }
- }
-
- if (tablet1.rowSize != 0) {
- session->insertAlignedTablets(tabletMap, true);
- tablet1.reset();
- tablet2.reset();
- tablet3.reset();
+ pair pairA("s1", TSDataType::INT32);
+ pair pairB("s2", TSDataType::DOUBLE);
+ pair pairC("s3", TSDataType::BOOLEAN);
+ vector> schemas;
+ schemas.push_back(pairA);
+ schemas.push_back(pairB);
+ schemas.push_back(pairC);
+
+ Tablet tablet1("root.sg1.d1", schemas, 100);
+ Tablet tablet2("root.sg1.d2", schemas, 100);
+ Tablet tablet3("root.sg1.d3", schemas, 100);
+
+ unordered_map tabletMap;
+ tabletMap["root.sg1.d1"] = &tablet1;
+ tabletMap["root.sg1.d2"] = &tablet2;
+ tabletMap["root.sg1.d3"] = &tablet3;
+
+ for (int64_t time = 0; time < 20; time++) {
+ size_t row1 = tablet1.rowSize++;
+ size_t row2 = tablet2.rowSize++;
+ size_t row3 = tablet3.rowSize++;
+ tablet1.timestamps[row1] = time;
+ tablet2.timestamps[row2] = time;
+ tablet3.timestamps[row3] = time;
+
+ int randVal11 = rand();
+ int randVal12 = rand();
+ int randVal13 = rand();
+ tablet1.addValue(0, row1, randVal11);
+ tablet2.addValue(0, row2, randVal12);
+ tablet3.addValue(0, row3, randVal13);
+
+ double randVal21 = rand() / 99.9;
+ double randVal22 = rand() / 99.9;
+ double randVal23 = rand() / 99.9;
+ tablet1.addValue(1, row1, randVal21);
+ tablet2.addValue(1, row2, randVal22);
+ tablet3.addValue(1, row3, randVal23);
+
+ bool randVal31 = (bool)(rand() % 2);
+ bool randVal32 = (bool)(rand() % 2);
+ bool randVal33 = (bool)(rand() % 2);
+ tablet1.addValue(2, row1, randVal31);
+ tablet2.addValue(2, row2, randVal32);
+ tablet3.addValue(2, row3, randVal33);
+
+ if (tablet1.rowSize == tablet1.maxRowNumber) {
+ session->insertAlignedTablets(tabletMap, true);
+
+ tablet1.reset();
+ tablet2.reset();
+ tablet3.reset();
}
+ }
+
+ if (tablet1.rowSize != 0) {
+ session->insertAlignedTablets(tabletMap, true);
+ tablet1.reset();
+ tablet2.reset();
+ tablet3.reset();
+ }
}
void insertNullableTabletWithAlignedTimeseries() {
- pair pairA("s1", TSDataType::INT32);
- pair pairB("s2", TSDataType::INT64);
- pair pairC("s3", TSDataType::BOOLEAN);
- vector> schemas;
- schemas.push_back(pairA);
- schemas.push_back(pairB);
- schemas.push_back(pairC);
-
- Tablet tablet("root.sg1.d4", schemas, 20);
- tablet.setAligned(true);
-
- for (int64_t time = 0; time < 20; time++) {
- size_t row = tablet.rowSize++;
- tablet.timestamps[row] = time;
- for (int i = 0; i < 3; i++) {
- int randVal1 = rand();
- int64_t randVal2 = rand();
- bool randVal3 = (bool)(rand() % 2);
- if (i == 0) {
- tablet.addValue(i, row, randVal1);
- } else if (i == 1) {
- tablet.addValue(i, row, randVal2);
- } else {
- tablet.addValue(i, row, randVal3);
- }
- // mark null value
- if ((row % 3) == (unsigned int) i) {
- tablet.bitMaps[i].mark(row);
- }
- }
- if (tablet.rowSize == tablet.maxRowNumber) {
- session->insertTablet(tablet, true);
- tablet.reset();
- }
+ pair pairA("s1", TSDataType::INT32);
+ pair pairB("s2", TSDataType::INT64);
+ pair pairC("s3", TSDataType::BOOLEAN);
+ vector> schemas;
+ schemas.push_back(pairA);
+ schemas.push_back(pairB);
+ schemas.push_back(pairC);
+
+ Tablet tablet("root.sg1.d4", schemas, 20);
+ tablet.setAligned(true);
+
+ for (int64_t time = 0; time < 20; time++) {
+ size_t row = tablet.rowSize++;
+ tablet.timestamps[row] = time;
+ for (int i = 0; i < 3; i++) {
+ int randVal1 = rand();
+ int64_t randVal2 = rand();
+ bool randVal3 = (bool)(rand() % 2);
+ if (i == 0) {
+ tablet.addValue(i, row, randVal1);
+ } else if (i == 1) {
+ tablet.addValue(i, row, randVal2);
+ } else {
+ tablet.addValue(i, row, randVal3);
+ }
+ // mark null value
+ if ((row % 3) == (unsigned int)i) {
+ tablet.bitMaps[i].mark(row);
+ }
}
-
- if (tablet.rowSize != 0) {
- session->insertTablet(tablet);
- tablet.reset();
+ if (tablet.rowSize == tablet.maxRowNumber) {
+ session->insertTablet(tablet, true);
+ tablet.reset();
}
+ }
+
+ if (tablet.rowSize != 0) {
+ session->insertTablet(tablet);
+ tablet.reset();
+ }
}
void query() {
- unique_ptr dataSet = session->executeQueryStatement("select * from root.sg1.**");
- cout << "timestamp" << " ";
- for (const string &name: dataSet->getColumnNames()) {
- cout << name << " ";
- }
- cout << endl;
-
- dataSet->setFetchSize(1024);
- while (dataSet->hasNext()) {
- cout << dataSet->next()->toString();
- }
- cout << endl;
-
- dataSet->closeOperationHandle();
+ unique_ptr dataSet = session->executeQueryStatement("select * from root.sg1.**");
+ cout << "timestamp"
+ << " ";
+ for (const string& name : dataSet->getColumnNames()) {
+ cout << name << " ";
+ }
+ cout << endl;
+
+ dataSet->setFetchSize(1024);
+ while (dataSet->hasNext()) {
+ cout << dataSet->next()->toString();
+ }
+ cout << endl;
+
+ dataSet->closeOperationHandle();
}
void deleteData() {
- string path = "root.**";
- int64_t deleteTime = 49;
- session->deleteData(path, deleteTime);
+ string path = "root.**";
+ int64_t deleteTime = 49;
+ session->deleteData(path, deleteTime);
}
void deleteTimeseries() {
- vector paths;
- vector alignedTimeseries = {"root.sg1.d1.s1", "root.sg1.d1.s2", "root.sg1.d1.s3", "root.sg1.d1.s4",
- "root.sg1.d2.s1", "root.sg1.d2.s2", "root.sg1.d2.s3",
- "root.sg1.d3.s1", "root.sg1.d3.s2", "root.sg1.d3.s3",
- "root.sg1.d4.s1", "root.sg1.d4.s2", "root.sg1.d4.s3",
- "root.sg2.d2.s1", "root.sg2.d2.s2", "root.sg2.d2.s3", };
- for (const string ×eries: alignedTimeseries) {
- if (session->checkTimeseriesExists(timeseries)) {
- paths.push_back(timeseries);
- }
+ vector paths;
+ vector alignedTimeseries = {
+ "root.sg1.d1.s1", "root.sg1.d1.s2", "root.sg1.d1.s3", "root.sg1.d1.s4",
+ "root.sg1.d2.s1", "root.sg1.d2.s2", "root.sg1.d2.s3", "root.sg1.d3.s1",
+ "root.sg1.d3.s2", "root.sg1.d3.s3", "root.sg1.d4.s1", "root.sg1.d4.s2",
+ "root.sg1.d4.s3", "root.sg2.d2.s1", "root.sg2.d2.s2", "root.sg2.d2.s3",
+ };
+ for (const string& timeseries : alignedTimeseries) {
+ if (session->checkTimeseriesExists(timeseries)) {
+ paths.push_back(timeseries);
}
- session->deleteTimeseries(paths);
+ }
+ session->deleteTimeseries(paths);
}
void deleteStorageGroups() {
- vector storageGroups;
- storageGroups.emplace_back("root.sg1");
- storageGroups.emplace_back("root.sg2");
- session->deleteStorageGroups(storageGroups);
+ vector storageGroups;
+ storageGroups.emplace_back("root.sg1");
+ storageGroups.emplace_back("root.sg2");
+ session->deleteStorageGroups(storageGroups);
}
-
int main() {
- LOG_LEVEL = LEVEL_DEBUG;
+ LOG_LEVEL = LEVEL_DEBUG;
- session = new Session("127.0.0.1", 6667, "root", "root");
+ session = new Session("127.0.0.1", 6667, "root", "root");
- cout << "session open\n" << endl;
- session->open(false);
+ cout << "session open\n" << endl;
+ session->open(false);
- cout << "setStorageGroup\n" << endl;
- try {
- session->setStorageGroup("root.sg1");
- }
- catch (IoTDBException &e) {
- string errorMessage(e.what());
- if (errorMessage.find("StorageGroupAlreadySetException") == string::npos) {
- cout << errorMessage << endl;
- //throw e;
- }
+ cout << "setStorageGroup\n" << endl;
+ try {
+ session->setStorageGroup("root.sg1");
+ } catch (IoTDBException& e) {
+ string errorMessage(e.what());
+ if (errorMessage.find("StorageGroupAlreadySetException") == string::npos) {
+ cout << errorMessage << endl;
+ //throw e;
}
+ }
- cout << "createAlignedTimeseries\n" << endl;
- createAlignedTimeseries();
+ cout << "createAlignedTimeseries\n" << endl;
+ createAlignedTimeseries();
- cout << "createSchemaTemplate\n" << endl;
- createSchemaTemplate();
+ cout << "createSchemaTemplate\n" << endl;
+ createSchemaTemplate();
- cout << "ActivateTemplate\n" << endl;
- ActivateTemplate();
+ cout << "ActivateTemplate\n" << endl;
+ ActivateTemplate();
- cout << "showDevices\n" << endl;
- showDevices();
+ cout << "showDevices\n" << endl;
+ showDevices();
- cout << "showTimeseries\n" << endl;
- showTimeseries();
+ cout << "showTimeseries\n" << endl;
+ showTimeseries();
- cout << "insertAlignedRecord\n" << endl;
- insertAlignedRecord();
+ cout << "insertAlignedRecord\n" << endl;
+ insertAlignedRecord();
- cout << "insertAlignedRecords\n" << endl;
- insertAlignedRecords();
+ cout << "insertAlignedRecords\n" << endl;
+ insertAlignedRecords();
- cout << "insertAlignedTablet" << endl;
- cout << "Insert " << DEFAULT_ROW_NUMBER << " records." << endl;
- time_t now1 = time(0);
- insertAlignedTablet();
- time_t now2 = time(0);
- time_t useTime = now2 - now1;
- cout << "Use time: " << useTime << "s.\n" << endl;
+ cout << "insertAlignedTablet" << endl;
+ cout << "Insert " << DEFAULT_ROW_NUMBER << " records." << endl;
+ time_t now1 = time(0);
+ insertAlignedTablet();
+ time_t now2 = time(0);
+ time_t useTime = now2 - now1;
+ cout << "Use time: " << useTime << "s.\n" << endl;
- cout << "insertAlignedTablets\n" << endl;
- insertAlignedTablets();
+ cout << "insertAlignedTablets\n" << endl;
+ insertAlignedTablets();
- cout << "insertNullableTabletWithAlignedTimeseries\n" << endl;
- insertNullableTabletWithAlignedTimeseries();
+ cout << "insertNullableTabletWithAlignedTimeseries\n" << endl;
+ insertNullableTabletWithAlignedTimeseries();
- cout << "query\n" << endl;
- query();
+ cout << "query\n" << endl;
+ query();
- cout << "deleteData\n" << endl;
- deleteData();
+ cout << "deleteData\n" << endl;
+ deleteData();
- cout << "deleteTimeseries\n" << endl;
- deleteTimeseries();
+ cout << "deleteTimeseries\n" << endl;
+ deleteTimeseries();
- cout << "deleteStorageGroups\n" << endl;
- deleteStorageGroups();
+ cout << "deleteStorageGroups\n" << endl;
+ deleteStorageGroups();
- cout << "session close\n" << endl;
- session->close();
+ cout << "session close\n" << endl;
+ session->close();
- delete session;
+ delete session;
- cout << "finished\n" << endl;
- return 0;
+ cout << "finished\n" << endl;
+ return 0;
}
diff --git a/example/client-cpp-example/src/MultiSvrNodeClient.cpp b/example/client-cpp-example/src/MultiSvrNodeClient.cpp
index 68e3e7230ca72..06e96ecd31bdf 100644
--- a/example/client-cpp-example/src/MultiSvrNodeClient.cpp
+++ b/example/client-cpp-example/src/MultiSvrNodeClient.cpp
@@ -30,118 +30,99 @@
namespace {
void RunTreeExample() {
- try {
- std::vector node_urls = {
- "127.0.0.1:6667", "127.0.0.1:6668", "127.0.0.1:6669"};
-
- auto builder = std::make_shared();
- auto session = std::shared_ptr(
- builder->username("root")
- ->password("root")
- ->nodeUrls(node_urls)
- ->build());
-
- session->open();
- if (!session->checkTimeseriesExists("root.test.d1.s1")) {
- session->createTimeseries("root.test.d1.s1", TSDataType::INT64,
- TSEncoding::RLE, CompressionType::SNAPPY);
- }
- session->deleteTimeseries("root.test.d1.s1");
- session->close();
- } catch (const std::exception& e) {
- std::cout << "Caught exception: " << e.what() << std::endl;
+ try {
+ std::vector node_urls = {"127.0.0.1:6667", "127.0.0.1:6668", "127.0.0.1:6669"};
+
+ auto builder = std::make_shared();
+ auto session = std::shared_ptr(
+ builder->username("root")->password("root")->nodeUrls(node_urls)->build());
+
+ session->open();
+ if (!session->checkTimeseriesExists("root.test.d1.s1")) {
+ session->createTimeseries("root.test.d1.s1", TSDataType::INT64, TSEncoding::RLE,
+ CompressionType::SNAPPY);
}
+ session->deleteTimeseries("root.test.d1.s1");
+ session->close();
+ } catch (const std::exception& e) {
+ std::cout << "Caught exception: " << e.what() << std::endl;
+ }
}
void RunTableExample() {
- try {
- std::vector node_urls = {
- "127.0.0.1:6669", "127.0.0.1:6668", "127.0.0.1:6667"};
-
- auto builder = std::make_shared();
- auto session = std::shared_ptr(
- builder->username("root")
- ->password("root")
- ->nodeUrls(node_urls)
- ->build());
-
- session->open();
-
- session->executeNonQueryStatement("DROP DATABASE IF EXISTS db1");
- session->executeNonQueryStatement("CREATE DATABASE db1");
- session->executeNonQueryStatement("DROP DATABASE IF EXISTS db2");
- session->executeNonQueryStatement("CREATE DATABASE db2");
-
- session->close();
- } catch (const std::exception& e) {
- std::cout << "Caught exception: " << e.what() << std::endl;
- }
-}
+ try {
+ std::vector node_urls = {"127.0.0.1:6669", "127.0.0.1:6668", "127.0.0.1:6667"};
+
+ auto builder = std::make_shared();
+ auto session = std::shared_ptr(
+ builder->username("root")->password("root")->nodeUrls(node_urls)->build());
+ session->open();
+
+ session->executeNonQueryStatement("DROP DATABASE IF EXISTS db1");
+ session->executeNonQueryStatement("CREATE DATABASE db1");
+ session->executeNonQueryStatement("DROP DATABASE IF EXISTS db2");
+ session->executeNonQueryStatement("CREATE DATABASE db2");
+
+ session->close();
+ } catch (const std::exception& e) {
+ std::cout << "Caught exception: " << e.what() << std::endl;
+ }
+}
// Example: continuously write/query data so you can manually stop a node
// to test client failover behavior.
void RunResilienceExample() {
- try {
- std::vector node_urls = {
- "127.0.0.1:6667", "127.0.0.1:6668", "127.0.0.1:6669"};
-
- auto builder = std::make_shared();
- auto session = std::shared_ptr(
- builder->username("root")
- ->password("root")
- ->nodeUrls(node_urls)
- ->build());
-
- session->open();
-
- if (!session->checkTimeseriesExists("root.resilience.d1.s1")) {
- session->createTimeseries("root.resilience.d1.s1", TSDataType::INT64,
- TSEncoding::RLE, CompressionType::SNAPPY);
- }
-
- std::cout << "Starting resilience test. "
- "Stop one node manually to see failover handling..."
- << std::endl;
-
- for (int i = 0; i < 60; ++i) { // run ~60 seconds
- int64_t timestamp = std::chrono::system_clock::now().time_since_epoch() /
- std::chrono::milliseconds(1);
- std::string value = to_string(i);
- const char* value_cstr = value.c_str();
-
- try {
- session->insertRecord("root.resilience.d1", timestamp,
- {"s1"}, {TSDataType::INT64},
- {const_cast(value_cstr)});
- std::cout << "[Insert] ts=" << timestamp << ", value=" << value
- << std::endl;
-
- auto dataset = session->executeQueryStatement(
- "SELECT s1 FROM root.resilience.d1 LIMIT 1");
- std::cout << "[Query] Got dataset: "
- << (dataset ? "Success" : "Null") << std::endl;
-
- } catch (const std::exception& e) {
- std::cout << "Caught exception during resilience loop: " << e.what()
- << std::endl;
- }
-
- std::this_thread::sleep_for(std::chrono::seconds(1));
- }
-
- session->close();
- } catch (const std::exception& e) {
- std::cout << "Caught exception in RunResilienceExample: " << e.what()
- << std::endl;
+ try {
+ std::vector node_urls = {"127.0.0.1:6667", "127.0.0.1:6668", "127.0.0.1:6669"};
+
+ auto builder = std::make_shared();
+ auto session = std::shared_ptr(
+ builder->username("root")->password("root")->nodeUrls(node_urls)->build());
+
+ session->open();
+
+ if (!session->checkTimeseriesExists("root.resilience.d1.s1")) {
+ session->createTimeseries("root.resilience.d1.s1", TSDataType::INT64, TSEncoding::RLE,
+ CompressionType::SNAPPY);
}
+
+ std::cout << "Starting resilience test. "
+ "Stop one node manually to see failover handling..."
+ << std::endl;
+
+ for (int i = 0; i < 60; ++i) { // run ~60 seconds
+ int64_t timestamp =
+ std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
+ std::string value = to_string(i);
+ const char* value_cstr = value.c_str();
+
+ try {
+ session->insertRecord("root.resilience.d1", timestamp, {"s1"}, {TSDataType::INT64},
+ {const_cast(value_cstr)});
+ std::cout << "[Insert] ts=" << timestamp << ", value=" << value << std::endl;
+
+ auto dataset = session->executeQueryStatement("SELECT s1 FROM root.resilience.d1 LIMIT 1");
+ std::cout << "[Query] Got dataset: " << (dataset ? "Success" : "Null") << std::endl;
+
+ } catch (const std::exception& e) {
+ std::cout << "Caught exception during resilience loop: " << e.what() << std::endl;
+ }
+
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+ }
+
+ session->close();
+ } catch (const std::exception& e) {
+ std::cout << "Caught exception in RunResilienceExample: " << e.what() << std::endl;
+ }
}
-} // namespace
+} // namespace
int main() {
- //RunTreeExample();
- //RunTableExample();
- RunResilienceExample();
- return 0;
+ //RunTreeExample();
+ //RunTableExample();
+ RunResilienceExample();
+ return 0;
}
diff --git a/example/client-cpp-example/src/SessionExample.cpp b/example/client-cpp-example/src/SessionExample.cpp
index 2803d18976cbf..d589759e8ed20 100644
--- a/example/client-cpp-example/src/SessionExample.cpp
+++ b/example/client-cpp-example/src/SessionExample.cpp
@@ -21,255 +21,256 @@
using namespace std;
-Session *session;
+Session* session;
void createTimeseries() {
- if (!session->checkTimeseriesExists("root.sg1.d1.s1")) {
- session->createTimeseries("root.sg1.d1.s1", TSDataType::BOOLEAN, TSEncoding::RLE,
- CompressionType::SNAPPY);
- }
- if (!session->checkTimeseriesExists("root.sg1.d1.s2")) {
- session->createTimeseries("root.sg1.d1.s2", TSDataType::INT32, TSEncoding::RLE,
- CompressionType::SNAPPY);
- }
- if (!session->checkTimeseriesExists("root.sg1.d1.s3")) {
- session->createTimeseries("root.sg1.d1.s3", TSDataType::FLOAT, TSEncoding::RLE,
- CompressionType::SNAPPY);
- }
-
- // create timeseries with tags and attributes
- if (!session->checkTimeseriesExists("root.sg1.d1.s4")) {
- map tags;
- tags["tag1"] = "v1";
- map attributes;
- attributes["description"] = "v1";
- session->createTimeseries("root.sg1.d1.s4", TSDataType::INT64, TSEncoding::RLE,
- CompressionType::SNAPPY, nullptr, &tags, &attributes, "temperature");
- }
+ if (!session->checkTimeseriesExists("root.sg1.d1.s1")) {
+ session->createTimeseries("root.sg1.d1.s1", TSDataType::BOOLEAN, TSEncoding::RLE,
+ CompressionType::SNAPPY);
+ }
+ if (!session->checkTimeseriesExists("root.sg1.d1.s2")) {
+ session->createTimeseries("root.sg1.d1.s2", TSDataType::INT32, TSEncoding::RLE,
+ CompressionType::SNAPPY);
+ }
+ if (!session->checkTimeseriesExists("root.sg1.d1.s3")) {
+ session->createTimeseries("root.sg1.d1.s3", TSDataType::FLOAT, TSEncoding::RLE,
+ CompressionType::SNAPPY);
+ }
+
+ // create timeseries with tags and attributes
+ if (!session->checkTimeseriesExists("root.sg1.d1.s4")) {
+ map tags;
+ tags["tag1"] = "v1";
+ map attributes;
+ attributes["description"] = "v1";
+ session->createTimeseries("root.sg1.d1.s4", TSDataType::INT64, TSEncoding::RLE,
+ CompressionType::SNAPPY, nullptr, &tags, &attributes, "temperature");
+ }
}
void createMultiTimeseries() {
- if (!session->checkTimeseriesExists("root.sg1.d2.s1") && !session->checkTimeseriesExists("root.sg1.d2.s2")) {
- vector paths;
- paths.emplace_back("root.sg1.d2.s1");
- paths.emplace_back("root.sg1.d2.s2");
- vector tsDataTypes;
- tsDataTypes.push_back(TSDataType::INT64);
- tsDataTypes.push_back(TSDataType::DOUBLE);
- vector tsEncodings;
- tsEncodings.push_back(TSEncoding::RLE);
- tsEncodings.push_back(TSEncoding::RLE);
- vector compressionTypes;
- compressionTypes.push_back(CompressionType::SNAPPY);
- compressionTypes.push_back(CompressionType::SNAPPY);
-
- vector