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> tagsList; - map tags; - tags["unit"] = "kg"; - tagsList.push_back(tags); - tagsList.push_back(tags); - - vector> attributesList; - map attributes; - attributes["minValue"] = "1"; - attributes["maxValue"] = "100"; - attributesList.push_back(attributes); - attributesList.push_back(attributes); - - vector alias; - alias.emplace_back("weight1"); - alias.emplace_back("weight2"); - - session->createMultiTimeseries(paths, tsDataTypes, tsEncodings, compressionTypes, nullptr, &tagsList, - &attributesList, &alias); - } + 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> tagsList; + map tags; + tags["unit"] = "kg"; + tagsList.push_back(tags); + tagsList.push_back(tags); + + vector> attributesList; + map attributes; + attributes["minValue"] = "1"; + attributes["maxValue"] = "100"; + attributesList.push_back(attributes); + attributesList.push_back(attributes); + + vector alias; + alias.emplace_back("weight1"); + alias.emplace_back("weight2"); + + session->createMultiTimeseries(paths, tsDataTypes, tsEncodings, compressionTypes, nullptr, + &tagsList, &attributesList, &alias); + } } void createSchemaTemplate() { - if (!session->checkTemplateExists("template1")) { - Template temp("template1", false); + if (!session->checkTemplateExists("template1")) { + Template temp("template1", false); - InternalNode iNodeD99("d99", false); + InternalNode iNodeD99("d99", false); - 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 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 insertRecord() { - string deviceId = "root.sg2.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("2"); - values.emplace_back("3"); - session->insertRecord(deviceId, time, measurements, values); - } + string deviceId = "root.sg2.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("2"); + values.emplace_back("3"); + session->insertRecord(deviceId, time, measurements, values); + } } void insertTablet() { - pair pairA("s1", TSDataType::BOOLEAN); - pair pairB("s2", TSDataType::INT32); - pair pairC("s3", TSDataType::FLOAT); - vector> schemas; - schemas.push_back(pairA); - schemas.push_back(pairB); - schemas.push_back(pairC); + pair pairA("s1", TSDataType::BOOLEAN); + pair pairB("s2", TSDataType::INT32); + pair pairC("s3", TSDataType::FLOAT); + vector> schemas; + schemas.push_back(pairA); + schemas.push_back(pairB); + schemas.push_back(pairC); - Tablet tablet("root.sg1.d1", schemas, 100); + Tablet tablet("root.sg1.d1", schemas, 100); - for (int64_t time = 0; time < 30; time++) { - size_t row = tablet.rowSize++; - tablet.timestamps[row] = time; + for (int64_t time = 0; time < 30; time++) { + size_t row = tablet.rowSize++; + tablet.timestamps[row] = time; - bool randVal1 = rand() % 2; - tablet.addValue(0, row, randVal1); + bool randVal1 = rand() % 2; + tablet.addValue(0, row, randVal1); - int randVal2 = rand(); - tablet.addValue(1, row, randVal2); + int randVal2 = rand(); + tablet.addValue(1, row, randVal2); - float randVal3 = (float)(rand() / 99.9); - tablet.addValue(2, row, randVal3); + float randVal3 = (float)(rand() / 99.9); + tablet.addValue(2, row, randVal3); - if (tablet.rowSize == tablet.maxRowNumber) { - session->insertTablet(tablet, true); - tablet.reset(); - } + 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 insertRecords() { - string deviceId = "root.sg2.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 < 30; time++) { - vector values; - values.emplace_back("1"); - values.emplace_back("2"); - values.emplace_back("3"); - - deviceIds.push_back(deviceId); - measurementsList.push_back(measurements); - valuesList.push_back(values); - timestamps.push_back(time); - if (time != 20 && time % 10 == 0) { - session->insertRecords(deviceIds, timestamps, measurementsList, valuesList); - deviceIds.clear(); - measurementsList.clear(); - valuesList.clear(); - timestamps.clear(); - } + string deviceId = "root.sg2.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 < 30; time++) { + vector values; + values.emplace_back("1"); + values.emplace_back("2"); + values.emplace_back("3"); + + deviceIds.push_back(deviceId); + measurementsList.push_back(measurements); + valuesList.push_back(values); + timestamps.push_back(time); + if (time != 20 && time % 10 == 0) { + session->insertRecords(deviceIds, timestamps, measurementsList, valuesList); + deviceIds.clear(); + measurementsList.clear(); + valuesList.clear(); + timestamps.clear(); } + } - session->insertRecords(deviceIds, timestamps, measurementsList, valuesList); + session->insertRecords(deviceIds, timestamps, measurementsList, valuesList); } void insertTablets() { - pair pairA("s1", TSDataType::INT64); - pair pairB("s2", TSDataType::DOUBLE); - pair pairC("s3", TSDataType::TEXT); - vector> schemas; - schemas.push_back(pairA); - schemas.push_back(pairB); - schemas.push_back(pairC); + pair pairA("s1", TSDataType::INT64); + pair pairB("s2", TSDataType::DOUBLE); + pair pairC("s3", TSDataType::TEXT); + vector> schemas; + schemas.push_back(pairA); + schemas.push_back(pairB); + schemas.push_back(pairC); - Tablet tablet1("root.sg1.d2", schemas, 100); - Tablet tablet2("root.sg1.d3", schemas, 100); + Tablet tablet1("root.sg1.d2", schemas, 100); + Tablet tablet2("root.sg1.d3", schemas, 100); - unordered_map tabletMap; - tabletMap["root.sg1.d2"] = &tablet1; - tabletMap["root.sg1.d3"] = &tablet2; + unordered_map tabletMap; + tabletMap["root.sg1.d2"] = &tablet1; + tabletMap["root.sg1.d3"] = &tablet2; - for (int64_t time = 0; time < 30; time++) { - size_t row1 = tablet1.rowSize++; - size_t row2 = tablet2.rowSize++; - tablet1.timestamps[row1] = time; - tablet2.timestamps[row2] = time; + for (int64_t time = 0; time < 30; time++) { + size_t row1 = tablet1.rowSize++; + size_t row2 = tablet2.rowSize++; + tablet1.timestamps[row1] = time; + tablet2.timestamps[row2] = time; - int64_t randVal11 = rand(); - tablet1.addValue(0, row1, randVal11); + int64_t randVal11 = rand(); + tablet1.addValue(0, row1, randVal11); - double randVal12 = rand() / 99.9; - tablet1.addValue(1, row1, randVal12); + double randVal12 = rand() / 99.9; + tablet1.addValue(1, row1, randVal12); - string randVal13 = "string" + to_string(rand()); - tablet1.addValue(2, row1, randVal13); + string randVal13 = "string" + to_string(rand()); + tablet1.addValue(2, row1, randVal13); - int64_t randVal21 = rand(); - tablet2.addValue(0, row2, randVal21); + int64_t randVal21 = rand(); + tablet2.addValue(0, row2, randVal21); - double randVal22 = rand() / 99.9; - tablet2.addValue(1, row2, randVal22); + double randVal22 = rand() / 99.9; + tablet2.addValue(1, row2, randVal22); - string randVal23 = "string" + to_string(rand()); - tablet2.addValue(2, row2, randVal23); + string randVal23 = "string" + to_string(rand()); + tablet2.addValue(2, row2, randVal23); - if (tablet1.rowSize == tablet1.maxRowNumber) { - session->insertTablets(tabletMap, true); + if (tablet1.rowSize == tablet1.maxRowNumber) { + session->insertTablets(tabletMap, true); - tablet1.reset(); - tablet2.reset(); - } + tablet1.reset(); + tablet2.reset(); } + } - if (tablet1.rowSize != 0) { - session->insertTablets(tabletMap, true); - tablet1.reset(); - tablet2.reset(); - } + if (tablet1.rowSize != 0) { + session->insertTablets(tabletMap, true); + tablet1.reset(); + tablet2.reset(); + } } void insertTabletWithNullValues() { - /* + /* * A Tablet example: * device1 * time s1, s2, s3 @@ -277,185 +278,184 @@ void insertTabletWithNullValues() { * 2, 2, null, 2 * 3, 3, 3, null */ - pair pairA("s1", TSDataType::INT64); - pair pairB("s2", TSDataType::INT64); - pair pairC("s3", TSDataType::INT64); - vector> schemas; - schemas.push_back(pairA); - schemas.push_back(pairB); - schemas.push_back(pairC); - - Tablet tablet("root.sg1.d4", schemas, 30); - - for (int64_t time = 0; time < 30; time++) { - size_t row = tablet.rowSize++; - tablet.timestamps[row] = time; - for (int i = 0; i < 3; i++) { - int64_t randVal = rand(); - tablet.addValue(i, row, randVal); - // 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::INT64); + pair pairB("s2", TSDataType::INT64); + pair pairC("s3", TSDataType::INT64); + vector> schemas; + schemas.push_back(pairA); + schemas.push_back(pairB); + schemas.push_back(pairC); + + Tablet tablet("root.sg1.d4", schemas, 30); + + for (int64_t time = 0; time < 30; time++) { + size_t row = tablet.rowSize++; + tablet.timestamps[row] = time; + for (int i = 0; i < 3; i++) { + int64_t randVal = rand(); + tablet.addValue(i, row, randVal); + // 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 nonQuery() { - session->executeNonQueryStatement("insert into root.sg1.d1(timestamp,s1) values(100, 1);"); + session->executeNonQueryStatement("insert into root.sg1.d1(timestamp,s1) values(100, 1);"); } void query() { - unique_ptr dataSet = session->executeQueryStatement("select s1, s2, s3 from root.**"); - 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 s1, s2, s3 from root.**"); + 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.sg1.d1.s1"; - int64_t deleteTime = 99; - session->deleteData(path, deleteTime); + string path = "root.sg1.d1.s1"; + int64_t deleteTime = 99; + session->deleteData(path, deleteTime); } void deleteTimeseries() { - vector paths; - vector timeseriesGrp = { "root.sg1.d1.s1", "root.sg1.d1.s2", "root.sg1.d1.s3", - "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.d1.s1", "root.sg2.d1.s2", "root.sg2.d1.s3" }; - for (const string& timeseries : timeseriesGrp) { - if (session->checkTimeseriesExists(timeseries)) { - paths.push_back(timeseries); - } + vector paths; + vector timeseriesGrp = { + "root.sg1.d1.s1", "root.sg1.d1.s2", "root.sg1.d1.s3", "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.d1.s1", "root.sg2.d1.s2", "root.sg2.d1.s3"}; + for (const string& timeseries : timeseriesGrp) { + 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); } void queryLast() { - unique_ptr dataSet = session->executeQueryStatement("select last s1,s2,s3 from root.**"); - for (const string &name: dataSet->getColumnNames()) { - cout << name << " "; - } - cout << endl; - - while (dataSet->hasNext()) { - cout << dataSet->next()->toString(); - } - cout << endl; - - dataSet->closeOperationHandle(); + unique_ptr dataSet = + session->executeQueryStatement("select last s1,s2,s3 from root.**"); + for (const string& name : dataSet->getColumnNames()) { + cout << name << " "; + } + cout << endl; + + while (dataSet->hasNext()) { + cout << dataSet->next()->toString(); + } + cout << endl; + + dataSet->closeOperationHandle(); } int main() { - LOG_LEVEL = LEVEL_DEBUG; - - session = new Session("127.0.0.1", 6667, "root", "root"); - session->open(false); - - cout << "setStorageGroup: root.sg1\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: root.sg2\n" << endl; - try { - session->setStorageGroup("root.sg2"); + LOG_LEVEL = LEVEL_DEBUG; + + session = new Session("127.0.0.1", 6667, "root", "root"); + session->open(false); + + cout << "setStorageGroup: root.sg1\n" << endl; + try { + session->setStorageGroup("root.sg1"); + } catch (IoTDBException& e) { + string errorMessage(e.what()); + if (errorMessage.find("StorageGroupAlreadySetException") == string::npos) { + cout << errorMessage << endl; } - catch (IoTDBException &e) { - string errorMessage(e.what()); - if (errorMessage.find("StorageGroupAlreadySetException") == string::npos) { - cout << errorMessage << endl; - } - //throw e; + //throw e; + } + + cout << "setStorageGroup: root.sg2\n" << endl; + try { + session->setStorageGroup("root.sg2"); + } catch (IoTDBException& e) { + string errorMessage(e.what()); + if (errorMessage.find("StorageGroupAlreadySetException") == string::npos) { + cout << errorMessage << endl; } + //throw e; + } - cout << "createTimeseries\n" << endl; - createTimeseries(); + cout << "createTimeseries\n" << endl; + createTimeseries(); - cout << "createMultiTimeseries\n" << endl; - createMultiTimeseries(); + cout << "createMultiTimeseries\n" << endl; + createMultiTimeseries(); - cout << "createSchemaTemplate\n" << endl; - createSchemaTemplate(); + cout << "createSchemaTemplate\n" << endl; + createSchemaTemplate(); - cout << "ActivateTemplate\n" << endl; - ActivateTemplate(); + cout << "ActivateTemplate\n" << endl; + ActivateTemplate(); - cout << "showTimeseries\n" << endl; - showTimeseries(); + cout << "showTimeseries\n" << endl; + showTimeseries(); - cout << "insertRecord\n" << endl; - insertRecord(); + cout << "insertRecord\n" << endl; + insertRecord(); - cout << "insertTablet\n" << endl; - insertTablet(); + cout << "insertTablet\n" << endl; + insertTablet(); - cout << "insertRecords\n" << endl; - insertRecords(); + cout << "insertRecords\n" << endl; + insertRecords(); - cout << "insertTablets\n" << endl; - insertTablets(); + cout << "insertTablets\n" << endl; + insertTablets(); - cout << "insertTabletWithNullValues\n" << endl; - insertTabletWithNullValues(); + cout << "insertTabletWithNullValues\n" << endl; + insertTabletWithNullValues(); - cout << "nonQuery\n" << endl; - nonQuery(); + cout << "nonQuery\n" << endl; + nonQuery(); - cout << "queryLast\n" << endl; - queryLast(); + cout << "queryLast\n" << endl; + queryLast(); - 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/TableModelSessionExample.cpp b/example/client-cpp-example/src/TableModelSessionExample.cpp index 7546f97d97052..3ae321e18f882 100644 --- a/example/client-cpp-example/src/TableModelSessionExample.cpp +++ b/example/client-cpp-example/src/TableModelSessionExample.cpp @@ -26,188 +26,184 @@ shared_ptr 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(); - } + 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(); - } + 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(); + } + 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; } -void Output(unique_ptr &dataSet) { - for (const string &name: dataSet->getColumnNames()) { - cout << name << " "; +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 << endl; - while (dataSet->hasNext()) { - cout << dataSet->next()->toString(); + + cout << "[Use db1 as database]\n" << endl; + try { + session->executeNonQueryStatement("USE db1"); + } catch (IoTDBException& e) { + cout << e.what() << endl; } - cout << endl; -} -void OutputWithType(unique_ptr &dataSet) { - for (const string &name: dataSet->getColumnNames()) { - cout << name << " "; + 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 << endl; - for (const string &type: dataSet->getColumnTypeList()) { - cout << type << " "; + + cout << "[Show Tables]\n" << endl; + try { + unique_ptr dataSet = session->executeQueryStatement("SHOW TABLES"); + Output(dataSet); + } catch (IoTDBException& e) { + cout << e.what() << endl; } - cout << endl; - while (dataSet->hasNext()) { - cout << dataSet->next()->toString(); + + 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 << endl; -} -int main() { + 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 = (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(); - - cout << "finished!\n" << endl; - } catch (IoTDBConnectionException &e) { - cout << e.what() << endl; - } catch (IoTDBException &e) { - cout << e.what() << endl; + session->executeNonQueryStatement("USE db2"); + } catch (IoTDBException& e) { + cout << e.what() << endl; } - return 0; + + 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(); + + cout << "finished!\n" << endl; + } catch (IoTDBConnectionException& e) { + cout << e.what() << endl; + } catch (IoTDBException& e) { + cout << e.what() << endl; + } + return 0; } \ No newline at end of file diff --git a/iotdb-client/client-cpp/README.md b/iotdb-client/client-cpp/README.md index 15b24e9f52043..21e251d92a549 100644 --- a/iotdb-client/client-cpp/README.md +++ b/iotdb-client/client-cpp/README.md @@ -96,6 +96,46 @@ After run verify `mvn clean verify -P with-cpp -pl iotdb-client/client-cpp -am` +## Code Formatting + +We use `clang-format` as the only formatter for C++ code and trigger it through Maven Spotless. + +### Required version + +The version is pinned in the root `pom.xml` as property `clang.format.version` (same approach as Apache TsFile). Use **clang-format 17.0.6** locally so Spotless agrees with CI. + +**JDK for Maven:** the C++ `clangFormat` step is registered only when running Maven on **JDK 11 or newer** (see the `spotless-cpp` profile in this module and in `client-cpp-example`). The repository root still supports JDK 8 for Java builds, but `spotless:check` / `spotless:apply` for C++ will not apply the clang-format rules if you use JDK 8. + +### Install clang-format 17.0.6 + +- Linux (Ubuntu): On **24.04+**, `sudo apt-get install -y clang-format-17`. On **22.04**, that package is not in the default archive; add the LLVM 17 repo with [apt.llvm.org](https://apt.llvm.org/) (e.g. `sudo ./llvm.sh 17`, as CI does). The script installs `clang-17` and related tools but **not** the `clang-format-17` package, so also run `sudo apt-get install -y clang-format-17`. Then point the default `clang-format` at 17.x (Spotless invokes `clang-format` on `PATH`; some releases default to another major version): + + `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` + +- macOS: `brew install llvm@17`, then e.g. `ln -sf "$(brew --prefix llvm@17)/bin/clang-format" "$(brew --prefix)/bin/clang-format"` and/or put `$(brew --prefix llvm@17)/bin` on your `PATH`. + +- Windows: `choco install llvm --version=17.0.6 --force -y` (CI uses `--force` like TsFile so the expected LLVM is selected). + +### Validate only (no changes) + +`./mvnw -P with-cpp -pl iotdb-client/client-cpp spotless:check` + +`./mvnw -P with-cpp -pl example/client-cpp-example spotless:check` + +### Auto-fix formatting + +`./mvnw -P with-cpp -pl iotdb-client/client-cpp spotless:apply` + +`./mvnw -P with-cpp -pl example/client-cpp-example spotless:apply` + +### Windows (PowerShell) + +PowerShell may treat a comma in `-pl` as an argument separator. Prefer the two commands above. If you need a single invocation, quote the whole `-pl` value, for example: + +`./mvnw -P with-cpp "-pl=iotdb-client/client-cpp,example/client-cpp-example" spotless:check` + ## Package Hierarchy If the compilation finishes successfully, the packaged zip file will be placed under diff --git a/iotdb-client/client-cpp/pom.xml b/iotdb-client/client-cpp/pom.xml index 88b70cebdf108..c92fab103684e 100644 --- a/iotdb-client/client-cpp/pom.xml +++ b/iotdb-client/client-cpp/pom.xml @@ -444,5 +444,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/iotdb-client/client-cpp/src/main/AbstractSessionBuilder.h b/iotdb-client/client-cpp/src/main/AbstractSessionBuilder.h index 9355e213c81bf..9f59504d3887b 100644 --- a/iotdb-client/client-cpp/src/main/AbstractSessionBuilder.h +++ b/iotdb-client/client-cpp/src/main/AbstractSessionBuilder.h @@ -24,36 +24,36 @@ class AbstractSessionBuilder { public: - static constexpr const char* DEFAULT_HOST = "localhost"; - static constexpr int DEFAULT_RPC_PORT = 6667; - static constexpr const char* DEFAULT_USERNAME = "root"; - static constexpr const char* DEFAULT_PASSWORD = "root"; - static constexpr int DEFAULT_FETCH_SIZE = 10000; - static constexpr int DEFAULT_CONNECT_TIMEOUT_MS = 3 * 1000; - static constexpr int DEFAULT_MAX_RETRIES = 3; - static constexpr int DEFAULT_RETRY_DELAY_MS = 500; - static constexpr const char* DEFAULT_SQL_DIALECT = "tree"; - static constexpr bool DEFAULT_ENABLE_AUTO_FETCH = true; - static constexpr bool DEFAULT_ENABLE_REDIRECTIONS = true; - static constexpr bool DEFAULT_ENABLE_RPC_COMPRESSION = false; + static constexpr const char* DEFAULT_HOST = "localhost"; + static constexpr int DEFAULT_RPC_PORT = 6667; + static constexpr const char* DEFAULT_USERNAME = "root"; + static constexpr const char* DEFAULT_PASSWORD = "root"; + static constexpr int DEFAULT_FETCH_SIZE = 10000; + static constexpr int DEFAULT_CONNECT_TIMEOUT_MS = 3 * 1000; + static constexpr int DEFAULT_MAX_RETRIES = 3; + static constexpr int DEFAULT_RETRY_DELAY_MS = 500; + static constexpr const char* DEFAULT_SQL_DIALECT = "tree"; + static constexpr bool DEFAULT_ENABLE_AUTO_FETCH = true; + static constexpr bool DEFAULT_ENABLE_REDIRECTIONS = true; + static constexpr bool DEFAULT_ENABLE_RPC_COMPRESSION = false; - std::string host = DEFAULT_HOST; - int rpcPort = DEFAULT_RPC_PORT; - std::string username = DEFAULT_USERNAME; - std::string password = DEFAULT_PASSWORD; - std::string zoneId = ""; - int fetchSize = DEFAULT_FETCH_SIZE; - int connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MS; - int maxRetries = DEFAULT_MAX_RETRIES; - int retryDelayMs = DEFAULT_RETRY_DELAY_MS; - std::string sqlDialect = DEFAULT_SQL_DIALECT; - std::string database = ""; - bool enableAutoFetch = DEFAULT_ENABLE_AUTO_FETCH; - bool enableRedirections = DEFAULT_ENABLE_REDIRECTIONS; - bool enableRPCCompression = DEFAULT_ENABLE_RPC_COMPRESSION; - std::vector nodeUrls; - bool useSSL = false; - std::string trustCertFilePath; + std::string host = DEFAULT_HOST; + int rpcPort = DEFAULT_RPC_PORT; + std::string username = DEFAULT_USERNAME; + std::string password = DEFAULT_PASSWORD; + std::string zoneId = ""; + int fetchSize = DEFAULT_FETCH_SIZE; + int connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MS; + int maxRetries = DEFAULT_MAX_RETRIES; + int retryDelayMs = DEFAULT_RETRY_DELAY_MS; + std::string sqlDialect = DEFAULT_SQL_DIALECT; + std::string database = ""; + bool enableAutoFetch = DEFAULT_ENABLE_AUTO_FETCH; + bool enableRedirections = DEFAULT_ENABLE_REDIRECTIONS; + bool enableRPCCompression = DEFAULT_ENABLE_RPC_COMPRESSION; + std::vector nodeUrls; + bool useSSL = false; + std::string trustCertFilePath; }; #endif // IOTDB_ABSTRACTSESSIONBUILDER_H \ No newline at end of file diff --git a/iotdb-client/client-cpp/src/main/Column.cpp b/iotdb-client/client-cpp/src/main/Column.cpp index 4c533676d075a..203fcefd8d9a5 100644 --- a/iotdb-client/client-cpp/src/main/Column.cpp +++ b/iotdb-client/client-cpp/src/main/Column.cpp @@ -20,340 +20,459 @@ #include "Column.h" #include "ColumnDecoder.h" -TimeColumn::TimeColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& values) +TimeColumn::TimeColumn(int32_t arrayOffset, int32_t positionCount, + const std::vector& values) : arrayOffset_(arrayOffset), positionCount_(positionCount), values_(values) { - if (arrayOffset < 0) throw IoTDBException("arrayOffset is negative"); - if (positionCount < 0) throw IoTDBException("positionCount is negative"); - if (static_cast(values.size()) - arrayOffset < positionCount) { - throw IoTDBException("values length is less than positionCount"); - } + if (arrayOffset < 0) + throw IoTDBException("arrayOffset is negative"); + if (positionCount < 0) + throw IoTDBException("positionCount is negative"); + if (static_cast(values.size()) - arrayOffset < positionCount) { + throw IoTDBException("values length is less than positionCount"); + } } -TSDataType::TSDataType TimeColumn::getDataType() const { return TSDataType::INT64; } -ColumnEncoding TimeColumn::getEncoding() const { return ColumnEncoding::Int64Array; } +TSDataType::TSDataType TimeColumn::getDataType() const { + return TSDataType::INT64; +} +ColumnEncoding TimeColumn::getEncoding() const { + return ColumnEncoding::Int64Array; +} int64_t TimeColumn::getLong(int32_t position) const { - return values_[position + arrayOffset_]; + return values_[position + arrayOffset_]; } -bool TimeColumn::mayHaveNull() const { return false; } -bool TimeColumn::isNull(int32_t position) const { return false; } -std::vector TimeColumn::isNulls() const { return {}; } +bool TimeColumn::mayHaveNull() const { + return false; +} +bool TimeColumn::isNull(int32_t position) const { + return false; +} +std::vector TimeColumn::isNulls() const { + return {}; +} -int32_t TimeColumn::getPositionCount() const { return positionCount_; } +int32_t TimeColumn::getPositionCount() const { + return positionCount_; +} -int64_t TimeColumn::getStartTime() const { return values_[arrayOffset_]; } -int64_t TimeColumn::getEndTime() const { return values_[positionCount_ + arrayOffset_ - 1]; } +int64_t TimeColumn::getStartTime() const { + return values_[arrayOffset_]; +} +int64_t TimeColumn::getEndTime() const { + return values_[positionCount_ + arrayOffset_ - 1]; +} -const std::vector& TimeColumn::getTimes() const { return values_; } -std::vector TimeColumn::getLongs() const { return getTimes(); } +const std::vector& TimeColumn::getTimes() const { + return values_; +} +std::vector TimeColumn::getLongs() const { + return getTimes(); +} BinaryColumn::BinaryColumn(int32_t arrayOffset, int32_t positionCount, - const std::vector& valueIsNull, const std::vector>& values) - : arrayOffset_(arrayOffset), positionCount_(positionCount), - valueIsNull_(valueIsNull), values_(values) { - if (arrayOffset < 0) throw IoTDBException("arrayOffset is negative"); - if (positionCount < 0) throw IoTDBException("positionCount is negative"); - if (static_cast(values.size()) - arrayOffset < positionCount) { - throw IoTDBException("values length is less than positionCount"); - } - if (!valueIsNull.empty() && static_cast(valueIsNull.size()) - arrayOffset < positionCount) { - throw IoTDBException("isNull length is less than positionCount"); - } -} - -TSDataType::TSDataType BinaryColumn::getDataType() const { return TSDataType::TSDataType::TEXT; } -ColumnEncoding BinaryColumn::getEncoding() const { return ColumnEncoding::BinaryArray; } + const std::vector& valueIsNull, + const std::vector>& values) + : arrayOffset_(arrayOffset), positionCount_(positionCount), valueIsNull_(valueIsNull), + values_(values) { + if (arrayOffset < 0) + throw IoTDBException("arrayOffset is negative"); + if (positionCount < 0) + throw IoTDBException("positionCount is negative"); + if (static_cast(values.size()) - arrayOffset < positionCount) { + throw IoTDBException("values length is less than positionCount"); + } + if (!valueIsNull.empty() && + static_cast(valueIsNull.size()) - arrayOffset < positionCount) { + throw IoTDBException("isNull length is less than positionCount"); + } +} + +TSDataType::TSDataType BinaryColumn::getDataType() const { + return TSDataType::TSDataType::TEXT; +} +ColumnEncoding BinaryColumn::getEncoding() const { + return ColumnEncoding::BinaryArray; +} std::shared_ptr BinaryColumn::getBinary(int32_t position) const { - return values_[position + arrayOffset_]; + return values_[position + arrayOffset_]; } -std::vector> BinaryColumn::getBinaries() const { return values_; } - +std::vector> BinaryColumn::getBinaries() const { + return values_; +} -bool BinaryColumn::mayHaveNull() const { return !valueIsNull_.empty(); } +bool BinaryColumn::mayHaveNull() const { + return !valueIsNull_.empty(); +} bool BinaryColumn::isNull(int32_t position) const { - return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_]; + return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_]; } std::vector BinaryColumn::isNulls() const { - if (!valueIsNull_.empty()) return valueIsNull_; + if (!valueIsNull_.empty()) + return valueIsNull_; - std::vector result(positionCount_, false); - return result; + std::vector result(positionCount_, false); + return result; } -int32_t BinaryColumn::getPositionCount() const { return positionCount_; } +int32_t BinaryColumn::getPositionCount() const { + return positionCount_; +} IntColumn::IntColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& valueIsNull, const std::vector& values) - : arrayOffset_(arrayOffset), positionCount_(positionCount), - valueNull_(valueIsNull), values_(values) { - if (arrayOffset < 0) throw IoTDBException("arrayOffset is negative"); - if (positionCount < 0) throw IoTDBException("positionCount is negative"); - if (static_cast(values.size()) - arrayOffset < positionCount) { - throw IoTDBException("values length is less than positionCount"); - } - if (!valueIsNull.empty() && static_cast(valueIsNull.size()) - arrayOffset < positionCount) { - throw IoTDBException("isNull length is less than positionCount"); - } + : arrayOffset_(arrayOffset), positionCount_(positionCount), valueNull_(valueIsNull), + values_(values) { + if (arrayOffset < 0) + throw IoTDBException("arrayOffset is negative"); + if (positionCount < 0) + throw IoTDBException("positionCount is negative"); + if (static_cast(values.size()) - arrayOffset < positionCount) { + throw IoTDBException("values length is less than positionCount"); + } + if (!valueIsNull.empty() && + static_cast(valueIsNull.size()) - arrayOffset < positionCount) { + throw IoTDBException("isNull length is less than positionCount"); + } } -TSDataType::TSDataType IntColumn::getDataType() const { return TSDataType::INT32; } -ColumnEncoding IntColumn::getEncoding() const { return ColumnEncoding::Int32Array; } +TSDataType::TSDataType IntColumn::getDataType() const { + return TSDataType::INT32; +} +ColumnEncoding IntColumn::getEncoding() const { + return ColumnEncoding::Int32Array; +} int32_t IntColumn::getInt(int32_t position) const { - return values_[position + arrayOffset_]; + return values_[position + arrayOffset_]; } -std::vector IntColumn::getInts() const { return values_; } +std::vector IntColumn::getInts() const { + return values_; +} -bool IntColumn::mayHaveNull() const { return !valueNull_.empty(); } +bool IntColumn::mayHaveNull() const { + return !valueNull_.empty(); +} bool IntColumn::isNull(int32_t position) const { - return !valueNull_.empty() && valueNull_[position + arrayOffset_]; + return !valueNull_.empty() && valueNull_[position + arrayOffset_]; } std::vector IntColumn::isNulls() const { - if (!valueNull_.empty()) return valueNull_; + if (!valueNull_.empty()) + return valueNull_; - std::vector result(positionCount_, false); - return result; + std::vector result(positionCount_, false); + return result; } -int32_t IntColumn::getPositionCount() const { return positionCount_; } +int32_t IntColumn::getPositionCount() const { + return positionCount_; +} FloatColumn::FloatColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& valueIsNull, const std::vector& values) - : arrayOffset_(arrayOffset), positionCount_(positionCount), - valueIsNull_(valueIsNull), values_(values) { - if (arrayOffset < 0) throw IoTDBException("arrayOffset is negative"); - if (positionCount < 0) throw IoTDBException("positionCount is negative"); - if (static_cast(values.size()) - arrayOffset < positionCount) { - throw IoTDBException("values length is less than positionCount"); - } - if (!valueIsNull.empty() && static_cast(valueIsNull.size()) - arrayOffset < positionCount) { - throw IoTDBException("isNull length is less than positionCount"); - } + : arrayOffset_(arrayOffset), positionCount_(positionCount), valueIsNull_(valueIsNull), + values_(values) { + if (arrayOffset < 0) + throw IoTDBException("arrayOffset is negative"); + if (positionCount < 0) + throw IoTDBException("positionCount is negative"); + if (static_cast(values.size()) - arrayOffset < positionCount) { + throw IoTDBException("values length is less than positionCount"); + } + if (!valueIsNull.empty() && + static_cast(valueIsNull.size()) - arrayOffset < positionCount) { + throw IoTDBException("isNull length is less than positionCount"); + } } -TSDataType::TSDataType FloatColumn::getDataType() const { return TSDataType::TSDataType::FLOAT; } -ColumnEncoding FloatColumn::getEncoding() const { return ColumnEncoding::Int32Array; } +TSDataType::TSDataType FloatColumn::getDataType() const { + return TSDataType::TSDataType::FLOAT; +} +ColumnEncoding FloatColumn::getEncoding() const { + return ColumnEncoding::Int32Array; +} float FloatColumn::getFloat(int32_t position) const { - return values_[position + arrayOffset_]; + return values_[position + arrayOffset_]; } -std::vector FloatColumn::getFloats() const { return values_; } +std::vector FloatColumn::getFloats() const { + return values_; +} -bool FloatColumn::mayHaveNull() const { return !valueIsNull_.empty(); } +bool FloatColumn::mayHaveNull() const { + return !valueIsNull_.empty(); +} bool FloatColumn::isNull(int32_t position) const { - return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_]; + return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_]; } std::vector FloatColumn::isNulls() const { - if (!valueIsNull_.empty()) return valueIsNull_; + if (!valueIsNull_.empty()) + return valueIsNull_; - std::vector result(positionCount_, false); - return result; + std::vector result(positionCount_, false); + return result; } -int32_t FloatColumn::getPositionCount() const { return positionCount_; } +int32_t FloatColumn::getPositionCount() const { + return positionCount_; +} LongColumn::LongColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& valueIsNull, const std::vector& values) - : arrayOffset_(arrayOffset), positionCount_(positionCount), - valueIsNull_(valueIsNull), values_(values) { - if (arrayOffset < 0) throw IoTDBException("arrayOffset is negative"); - if (positionCount < 0) throw IoTDBException("positionCount is negative"); - if (static_cast(values.size()) - arrayOffset < positionCount) { - throw IoTDBException("values length is less than positionCount"); - } - if (!valueIsNull.empty() && static_cast(valueIsNull.size()) - arrayOffset < positionCount) { - throw IoTDBException("isNull length is less than positionCount"); - } + : arrayOffset_(arrayOffset), positionCount_(positionCount), valueIsNull_(valueIsNull), + values_(values) { + if (arrayOffset < 0) + throw IoTDBException("arrayOffset is negative"); + if (positionCount < 0) + throw IoTDBException("positionCount is negative"); + if (static_cast(values.size()) - arrayOffset < positionCount) { + throw IoTDBException("values length is less than positionCount"); + } + if (!valueIsNull.empty() && + static_cast(valueIsNull.size()) - arrayOffset < positionCount) { + throw IoTDBException("isNull length is less than positionCount"); + } } -TSDataType::TSDataType LongColumn::getDataType() const { return TSDataType::TSDataType::INT64; } -ColumnEncoding LongColumn::getEncoding() const { return ColumnEncoding::Int64Array; } +TSDataType::TSDataType LongColumn::getDataType() const { + return TSDataType::TSDataType::INT64; +} +ColumnEncoding LongColumn::getEncoding() const { + return ColumnEncoding::Int64Array; +} int64_t LongColumn::getLong(int32_t position) const { - return values_[position + arrayOffset_]; + return values_[position + arrayOffset_]; } -std::vector LongColumn::getLongs() const { return values_; } +std::vector LongColumn::getLongs() const { + return values_; +} -bool LongColumn::mayHaveNull() const { return !valueIsNull_.empty(); } +bool LongColumn::mayHaveNull() const { + return !valueIsNull_.empty(); +} bool LongColumn::isNull(int32_t position) const { - return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_]; + return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_]; } std::vector LongColumn::isNulls() const { - if (!valueIsNull_.empty()) return valueIsNull_; + if (!valueIsNull_.empty()) + return valueIsNull_; - std::vector result(positionCount_, false); - return result; + std::vector result(positionCount_, false); + return result; } -int32_t LongColumn::getPositionCount() const { return positionCount_; } +int32_t LongColumn::getPositionCount() const { + return positionCount_; +} DoubleColumn::DoubleColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& valueIsNull, const std::vector& values) - : arrayOffset_(arrayOffset), positionCount_(positionCount), - valueIsNull_(valueIsNull), values_(values) { - if (arrayOffset < 0) throw IoTDBException("arrayOffset is negative"); - if (positionCount < 0) throw IoTDBException("positionCount is negative"); - if (static_cast(values.size()) - arrayOffset < positionCount) { - throw IoTDBException("values length is less than positionCount"); - } - if (!valueIsNull.empty() && static_cast(valueIsNull.size()) - arrayOffset < positionCount) { - throw IoTDBException("isNull length is less than positionCount"); - } + : arrayOffset_(arrayOffset), positionCount_(positionCount), valueIsNull_(valueIsNull), + values_(values) { + if (arrayOffset < 0) + throw IoTDBException("arrayOffset is negative"); + if (positionCount < 0) + throw IoTDBException("positionCount is negative"); + if (static_cast(values.size()) - arrayOffset < positionCount) { + throw IoTDBException("values length is less than positionCount"); + } + if (!valueIsNull.empty() && + static_cast(valueIsNull.size()) - arrayOffset < positionCount) { + throw IoTDBException("isNull length is less than positionCount"); + } } -TSDataType::TSDataType DoubleColumn::getDataType() const { return TSDataType::TSDataType::DOUBLE; } -ColumnEncoding DoubleColumn::getEncoding() const { return ColumnEncoding::Int64Array; } +TSDataType::TSDataType DoubleColumn::getDataType() const { + return TSDataType::TSDataType::DOUBLE; +} +ColumnEncoding DoubleColumn::getEncoding() const { + return ColumnEncoding::Int64Array; +} double DoubleColumn::getDouble(int32_t position) const { - return values_[position + arrayOffset_]; + return values_[position + arrayOffset_]; } -std::vector DoubleColumn::getDoubles() const { return values_; } +std::vector DoubleColumn::getDoubles() const { + return values_; +} -bool DoubleColumn::mayHaveNull() const { return !valueIsNull_.empty(); } +bool DoubleColumn::mayHaveNull() const { + return !valueIsNull_.empty(); +} bool DoubleColumn::isNull(int32_t position) const { - return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_]; + return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_]; } std::vector DoubleColumn::isNulls() const { - if (!valueIsNull_.empty()) return valueIsNull_; + if (!valueIsNull_.empty()) + return valueIsNull_; - std::vector result(positionCount_, false); - return result; + std::vector result(positionCount_, false); + return result; } -int32_t DoubleColumn::getPositionCount() const { return positionCount_; } +int32_t DoubleColumn::getPositionCount() const { + return positionCount_; +} BooleanColumn::BooleanColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& valueIsNull, const std::vector& values) - : arrayOffset_(arrayOffset), positionCount_(positionCount), - valueIsNull_(valueIsNull), values_(values) { - if (arrayOffset < 0) throw IoTDBException("arrayOffset is negative"); - if (positionCount < 0) throw IoTDBException("positionCount is negative"); - if (static_cast(values.size()) - arrayOffset < positionCount) { - throw IoTDBException("values length is less than positionCount"); - } - if (!valueIsNull.empty() && static_cast(valueIsNull.size()) - arrayOffset < positionCount) { - throw IoTDBException("isNull length is less than positionCount"); - } + : arrayOffset_(arrayOffset), positionCount_(positionCount), valueIsNull_(valueIsNull), + values_(values) { + if (arrayOffset < 0) + throw IoTDBException("arrayOffset is negative"); + if (positionCount < 0) + throw IoTDBException("positionCount is negative"); + if (static_cast(values.size()) - arrayOffset < positionCount) { + throw IoTDBException("values length is less than positionCount"); + } + if (!valueIsNull.empty() && + static_cast(valueIsNull.size()) - arrayOffset < positionCount) { + throw IoTDBException("isNull length is less than positionCount"); + } } -TSDataType::TSDataType BooleanColumn::getDataType() const { return TSDataType::TSDataType::BOOLEAN; } -ColumnEncoding BooleanColumn::getEncoding() const { return ColumnEncoding::ByteArray; } +TSDataType::TSDataType BooleanColumn::getDataType() const { + return TSDataType::TSDataType::BOOLEAN; +} +ColumnEncoding BooleanColumn::getEncoding() const { + return ColumnEncoding::ByteArray; +} bool BooleanColumn::getBoolean(int32_t position) const { - return values_[position + arrayOffset_]; + return values_[position + arrayOffset_]; } -std::vector BooleanColumn::getBooleans() const { return values_; } +std::vector BooleanColumn::getBooleans() const { + return values_; +} -bool BooleanColumn::mayHaveNull() const { return !valueIsNull_.empty(); } +bool BooleanColumn::mayHaveNull() const { + return !valueIsNull_.empty(); +} bool BooleanColumn::isNull(int32_t position) const { - return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_]; + return !valueIsNull_.empty() && valueIsNull_[position + arrayOffset_]; } std::vector BooleanColumn::isNulls() const { - if (!valueIsNull_.empty()) return valueIsNull_; + if (!valueIsNull_.empty()) + return valueIsNull_; - std::vector result(positionCount_, false); - return result; + std::vector result(positionCount_, false); + return result; } -int32_t BooleanColumn::getPositionCount() const { return positionCount_; } +int32_t BooleanColumn::getPositionCount() const { + return positionCount_; +} RunLengthEncodedColumn::RunLengthEncodedColumn(std::shared_ptr value, int32_t positionCount) : value_(value), positionCount_(positionCount) { - if (!value) throw IoTDBException("value is null"); - if (value->getPositionCount() != 1) { - throw IoTDBException("Expected value to contain a single position"); - } - if (positionCount < 0) throw IoTDBException("positionCount is negative"); + if (!value) + throw IoTDBException("value is null"); + if (value->getPositionCount() != 1) { + throw IoTDBException("Expected value to contain a single position"); + } + if (positionCount < 0) + throw IoTDBException("positionCount is negative"); } -std::shared_ptr RunLengthEncodedColumn::getValue() const { return value_; } +std::shared_ptr RunLengthEncodedColumn::getValue() const { + return value_; +} -TSDataType::TSDataType RunLengthEncodedColumn::getDataType() const { return value_->getDataType(); } -ColumnEncoding RunLengthEncodedColumn::getEncoding() const { return ColumnEncoding::Rle; } +TSDataType::TSDataType RunLengthEncodedColumn::getDataType() const { + return value_->getDataType(); +} +ColumnEncoding RunLengthEncodedColumn::getEncoding() const { + return ColumnEncoding::Rle; +} bool RunLengthEncodedColumn::getBoolean(int32_t position) const { - return value_->getBoolean(0); + return value_->getBoolean(0); } int32_t RunLengthEncodedColumn::getInt(int32_t position) const { - return value_->getInt(0); + return value_->getInt(0); } int64_t RunLengthEncodedColumn::getLong(int32_t position) const { - return value_->getLong(0); + return value_->getLong(0); } float RunLengthEncodedColumn::getFloat(int32_t position) const { - return value_->getFloat(0); + return value_->getFloat(0); } double RunLengthEncodedColumn::getDouble(int32_t position) const { - return value_->getDouble(0); + return value_->getDouble(0); } std::shared_ptr RunLengthEncodedColumn::getBinary(int32_t position) const { - return value_->getBinary(0); + return value_->getBinary(0); } std::vector RunLengthEncodedColumn::getBooleans() const { - bool v = value_->getBoolean(0); - return std::vector(positionCount_, v); + bool v = value_->getBoolean(0); + return std::vector(positionCount_, v); } std::vector RunLengthEncodedColumn::getInts() const { - int32_t v = value_->getInt(0); - return std::vector(positionCount_, v); + int32_t v = value_->getInt(0); + return std::vector(positionCount_, v); } std::vector RunLengthEncodedColumn::getLongs() const { - int64_t v = value_->getLong(0); - return std::vector(positionCount_, v); + int64_t v = value_->getLong(0); + return std::vector(positionCount_, v); } std::vector RunLengthEncodedColumn::getFloats() const { - float v = value_->getFloat(0); - return std::vector(positionCount_, v); + float v = value_->getFloat(0); + return std::vector(positionCount_, v); } std::vector RunLengthEncodedColumn::getDoubles() const { - double v = value_->getDouble(0); - return std::vector(positionCount_, v); + double v = value_->getDouble(0); + return std::vector(positionCount_, v); } std::vector> RunLengthEncodedColumn::getBinaries() const { - auto v = value_->getBinary(0); - return std::vector>(positionCount_, v); + auto v = value_->getBinary(0); + return std::vector>(positionCount_, v); } -bool RunLengthEncodedColumn::mayHaveNull() const { return value_->mayHaveNull(); } +bool RunLengthEncodedColumn::mayHaveNull() const { + return value_->mayHaveNull(); +} bool RunLengthEncodedColumn::isNull(int32_t position) const { - return value_->isNull(0); + return value_->isNull(0); } std::vector RunLengthEncodedColumn::isNulls() const { - bool v = value_->isNull(0); - return std::vector(positionCount_, v); + bool v = value_->isNull(0); + return std::vector(positionCount_, v); } -int32_t RunLengthEncodedColumn::getPositionCount() const { return positionCount_; } +int32_t RunLengthEncodedColumn::getPositionCount() const { + return positionCount_; +} diff --git a/iotdb-client/client-cpp/src/main/Column.h b/iotdb-client/client-cpp/src/main/Column.h index 04f611f41a874..8794e7b8d5e34 100644 --- a/iotdb-client/client-cpp/src/main/Column.h +++ b/iotdb-client/client-cpp/src/main/Column.h @@ -27,327 +27,318 @@ #include "Common.h" #include "ColumnDecoder.h" -enum class ColumnEncoding : uint8_t { - ByteArray, - Int32Array, - Int64Array, - BinaryArray, - Rle -}; +enum class ColumnEncoding : uint8_t { ByteArray, Int32Array, Int64Array, BinaryArray, Rle }; class Binary { public: - explicit Binary(std::vector data) : data_(std::move(data)) { - } + explicit Binary(std::vector data) : data_(std::move(data)) {} - const std::vector& getData() const { return data_; } + const std::vector& getData() const { + return data_; + } - std::string getStringValue() const { - return {data_.begin(), data_.end()}; - } + std::string getStringValue() const { + return {data_.begin(), data_.end()}; + } private: - std::vector data_; + std::vector data_; }; - const std::map> kEncodingToDecoder = { {ColumnEncoding::Int32Array, std::make_shared()}, {ColumnEncoding::Int64Array, std::make_shared()}, {ColumnEncoding::ByteArray, std::make_shared()}, {ColumnEncoding::BinaryArray, std::make_shared()}, - {ColumnEncoding::Rle, std::make_shared()} -}; + {ColumnEncoding::Rle, std::make_shared()}}; -const std::map kByteToEncoding = { - {0, ColumnEncoding::ByteArray}, - {1, ColumnEncoding::Int32Array}, - {2, ColumnEncoding::Int64Array}, - {3, ColumnEncoding::BinaryArray}, - {4, ColumnEncoding::Rle} -}; +const std::map kByteToEncoding = {{0, ColumnEncoding::ByteArray}, + {1, ColumnEncoding::Int32Array}, + {2, ColumnEncoding::Int64Array}, + {3, ColumnEncoding::BinaryArray}, + {4, ColumnEncoding::Rle}}; inline std::shared_ptr getColumnDecoder(ColumnEncoding encoding) { - auto it = kEncodingToDecoder.find(encoding); - if (it == kEncodingToDecoder.end()) { - throw IoTDBException("Unsupported column encoding"); - } - return it->second; + auto it = kEncodingToDecoder.find(encoding); + if (it == kEncodingToDecoder.end()) { + throw IoTDBException("Unsupported column encoding"); + } + return it->second; } inline ColumnEncoding getColumnEncodingByByte(uint8_t b) { - auto it = kByteToEncoding.find(b); - if (it == kByteToEncoding.end()) { - throw IoTDBException("Invalid encoding value: " + std::to_string(b)); - } - return it->second; + auto it = kByteToEncoding.find(b); + if (it == kByteToEncoding.end()) { + throw IoTDBException("Invalid encoding value: " + std::to_string(b)); + } + return it->second; } class Column { public: - virtual ~Column() = default; + virtual ~Column() = default; - virtual TSDataType::TSDataType getDataType() const = 0; - virtual ColumnEncoding getEncoding() const = 0; + virtual TSDataType::TSDataType getDataType() const = 0; + virtual ColumnEncoding getEncoding() const = 0; - virtual bool getBoolean(int32_t position) const { - throw IoTDBException("Unsupported operation: getBoolean"); - } + virtual bool getBoolean(int32_t position) const { + throw IoTDBException("Unsupported operation: getBoolean"); + } - virtual int32_t getInt(int32_t position) const { - throw IoTDBException("Unsupported operation: getInt"); - } + virtual int32_t getInt(int32_t position) const { + throw IoTDBException("Unsupported operation: getInt"); + } - virtual int64_t getLong(int32_t position) const { - throw IoTDBException("Unsupported operation: getLong"); - } + virtual int64_t getLong(int32_t position) const { + throw IoTDBException("Unsupported operation: getLong"); + } - virtual float getFloat(int32_t position) const { - throw IoTDBException("Unsupported operation: getFloat"); - } + virtual float getFloat(int32_t position) const { + throw IoTDBException("Unsupported operation: getFloat"); + } - virtual double getDouble(int32_t position) const { - throw IoTDBException("Unsupported operation: getDouble"); - } + virtual double getDouble(int32_t position) const { + throw IoTDBException("Unsupported operation: getDouble"); + } - virtual std::shared_ptr getBinary(int32_t position) const { - throw IoTDBException("Unsupported operation: getBinary"); - } + virtual std::shared_ptr getBinary(int32_t position) const { + throw IoTDBException("Unsupported operation: getBinary"); + } - virtual std::vector getBooleans() const { - throw IoTDBException("Unsupported operation: getBooleans"); - } + virtual std::vector getBooleans() const { + throw IoTDBException("Unsupported operation: getBooleans"); + } - virtual std::vector getInts() const { - throw IoTDBException("Unsupported operation: getInts"); - } + virtual std::vector getInts() const { + throw IoTDBException("Unsupported operation: getInts"); + } - virtual std::vector getLongs() const { - throw IoTDBException("Unsupported operation: getLongs"); - } + virtual std::vector getLongs() const { + throw IoTDBException("Unsupported operation: getLongs"); + } - virtual std::vector getFloats() const { - throw IoTDBException("Unsupported operation: getFloats"); - } + virtual std::vector getFloats() const { + throw IoTDBException("Unsupported operation: getFloats"); + } - virtual std::vector getDoubles() const { - throw IoTDBException("Unsupported operation: getDoubles"); - } + virtual std::vector getDoubles() const { + throw IoTDBException("Unsupported operation: getDoubles"); + } - virtual std::vector> getBinaries() const { - throw IoTDBException("Unsupported operation: getBinaries"); - } + virtual std::vector> getBinaries() const { + throw IoTDBException("Unsupported operation: getBinaries"); + } - virtual bool mayHaveNull() const = 0; - virtual bool isNull(int32_t position) const = 0; - virtual std::vector isNulls() const = 0; + virtual bool mayHaveNull() const = 0; + virtual bool isNull(int32_t position) const = 0; + virtual std::vector isNulls() const = 0; - virtual int32_t getPositionCount() const = 0; + virtual int32_t getPositionCount() const = 0; }; class TimeColumn : public Column { public: - TimeColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& values); + TimeColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& values); - TSDataType::TSDataType getDataType() const override; - ColumnEncoding getEncoding() const override; + TSDataType::TSDataType getDataType() const override; + ColumnEncoding getEncoding() const override; - int64_t getLong(int32_t position) const override; + int64_t getLong(int32_t position) const override; - bool mayHaveNull() const override; - bool isNull(int32_t position) const override; - std::vector isNulls() const override; + bool mayHaveNull() const override; + bool isNull(int32_t position) const override; + std::vector isNulls() const override; - int32_t getPositionCount() const override; + int32_t getPositionCount() const override; - int64_t getStartTime() const; - int64_t getEndTime() const; + int64_t getStartTime() const; + int64_t getEndTime() const; - const std::vector& getTimes() const; - std::vector getLongs() const override; + const std::vector& getTimes() const; + std::vector getLongs() const override; private: - int32_t arrayOffset_; - int32_t positionCount_; - std::vector values_; + int32_t arrayOffset_; + int32_t positionCount_; + std::vector values_; }; class BinaryColumn : public Column { public: - BinaryColumn(int32_t arrayOffset, int32_t positionCount, - const std::vector& valueIsNull, const std::vector>& values); + BinaryColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& valueIsNull, + const std::vector>& values); - TSDataType::TSDataType getDataType() const override; - ColumnEncoding getEncoding() const override; + TSDataType::TSDataType getDataType() const override; + ColumnEncoding getEncoding() const override; - std::shared_ptr getBinary(int32_t position) const override; - std::vector> getBinaries() const override; + std::shared_ptr getBinary(int32_t position) const override; + std::vector> getBinaries() const override; - bool mayHaveNull() const override; - bool isNull(int32_t position) const override; - std::vector isNulls() const override; + bool mayHaveNull() const override; + bool isNull(int32_t position) const override; + std::vector isNulls() const override; - int32_t getPositionCount() const override; + int32_t getPositionCount() const override; private: - int32_t arrayOffset_; - int32_t positionCount_; - std::vector valueIsNull_; - std::vector> values_; + int32_t arrayOffset_; + int32_t positionCount_; + std::vector valueIsNull_; + std::vector> values_; }; class IntColumn : public Column { public: - IntColumn(int32_t arrayOffset, int32_t positionCount, - const std::vector& valueIsNull, const std::vector& values); + IntColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& valueIsNull, + const std::vector& values); - TSDataType::TSDataType getDataType() const override; - ColumnEncoding getEncoding() const override; + TSDataType::TSDataType getDataType() const override; + ColumnEncoding getEncoding() const override; - int32_t getInt(int32_t position) const override; - std::vector getInts() const override; + int32_t getInt(int32_t position) const override; + std::vector getInts() const override; - bool mayHaveNull() const override; - bool isNull(int32_t position) const override; - std::vector isNulls() const override; + bool mayHaveNull() const override; + bool isNull(int32_t position) const override; + std::vector isNulls() const override; - int32_t getPositionCount() const override; + int32_t getPositionCount() const override; private: - int32_t arrayOffset_; - int32_t positionCount_; - std::vector valueNull_; - std::vector values_; + int32_t arrayOffset_; + int32_t positionCount_; + std::vector valueNull_; + std::vector values_; }; class FloatColumn : public Column { public: - FloatColumn(int32_t arrayOffset, int32_t positionCount, - const std::vector& valueIsNull, const std::vector& values); + FloatColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& valueIsNull, + const std::vector& values); - TSDataType::TSDataType getDataType() const override; - ColumnEncoding getEncoding() const override; + TSDataType::TSDataType getDataType() const override; + ColumnEncoding getEncoding() const override; - float getFloat(int32_t position) const override; - std::vector getFloats() const override; + float getFloat(int32_t position) const override; + std::vector getFloats() const override; - bool mayHaveNull() const override; - bool isNull(int32_t position) const override; - std::vector isNulls() const override; + bool mayHaveNull() const override; + bool isNull(int32_t position) const override; + std::vector isNulls() const override; - int32_t getPositionCount() const override; + int32_t getPositionCount() const override; private: - int32_t arrayOffset_; - int32_t positionCount_; - std::vector valueIsNull_; - std::vector values_; + int32_t arrayOffset_; + int32_t positionCount_; + std::vector valueIsNull_; + std::vector values_; }; class LongColumn : public Column { public: - LongColumn(int32_t arrayOffset, int32_t positionCount, - const std::vector& valueIsNull, const std::vector& values); + LongColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& valueIsNull, + const std::vector& values); - TSDataType::TSDataType getDataType() const override; - ColumnEncoding getEncoding() const override; + TSDataType::TSDataType getDataType() const override; + ColumnEncoding getEncoding() const override; - int64_t getLong(int32_t position) const override; - std::vector getLongs() const override; + int64_t getLong(int32_t position) const override; + std::vector getLongs() const override; - bool mayHaveNull() const override; - bool isNull(int32_t position) const override; - std::vector isNulls() const override; + bool mayHaveNull() const override; + bool isNull(int32_t position) const override; + std::vector isNulls() const override; - int32_t getPositionCount() const override; + int32_t getPositionCount() const override; private: - int32_t arrayOffset_; - int32_t positionCount_; - std::vector valueIsNull_; - std::vector values_; + int32_t arrayOffset_; + int32_t positionCount_; + std::vector valueIsNull_; + std::vector values_; }; class DoubleColumn : public Column { public: - DoubleColumn(int32_t arrayOffset, int32_t positionCount, - const std::vector& valueIsNull, const std::vector& values); + DoubleColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& valueIsNull, + const std::vector& values); - TSDataType::TSDataType getDataType() const override; - ColumnEncoding getEncoding() const override; + TSDataType::TSDataType getDataType() const override; + ColumnEncoding getEncoding() const override; - double getDouble(int32_t position) const override; - std::vector getDoubles() const override; + double getDouble(int32_t position) const override; + std::vector getDoubles() const override; - bool mayHaveNull() const override; - bool isNull(int32_t position) const override; - std::vector isNulls() const override; + bool mayHaveNull() const override; + bool isNull(int32_t position) const override; + std::vector isNulls() const override; - int32_t getPositionCount() const override; + int32_t getPositionCount() const override; private: - int32_t arrayOffset_; - int32_t positionCount_; - std::vector valueIsNull_; - std::vector values_; + int32_t arrayOffset_; + int32_t positionCount_; + std::vector valueIsNull_; + std::vector values_; }; class BooleanColumn : public Column { public: - BooleanColumn(int32_t arrayOffset, int32_t positionCount, - const std::vector& valueIsNull, const std::vector& values); + BooleanColumn(int32_t arrayOffset, int32_t positionCount, const std::vector& valueIsNull, + const std::vector& values); - TSDataType::TSDataType getDataType() const override; - ColumnEncoding getEncoding() const override; + TSDataType::TSDataType getDataType() const override; + ColumnEncoding getEncoding() const override; - bool getBoolean(int32_t position) const override; - std::vector getBooleans() const override; + bool getBoolean(int32_t position) const override; + std::vector getBooleans() const override; - bool mayHaveNull() const override; - bool isNull(int32_t position) const override; - std::vector isNulls() const override; + bool mayHaveNull() const override; + bool isNull(int32_t position) const override; + std::vector isNulls() const override; - int32_t getPositionCount() const override; + int32_t getPositionCount() const override; private: - int32_t arrayOffset_; - int32_t positionCount_; - std::vector valueIsNull_; - std::vector values_; + int32_t arrayOffset_; + int32_t positionCount_; + std::vector valueIsNull_; + std::vector values_; }; class RunLengthEncodedColumn : public Column { public: - RunLengthEncodedColumn(std::shared_ptr value, int32_t positionCount); + RunLengthEncodedColumn(std::shared_ptr value, int32_t positionCount); - std::shared_ptr getValue() const; + std::shared_ptr getValue() const; - TSDataType::TSDataType getDataType() const override; - ColumnEncoding getEncoding() const override; + TSDataType::TSDataType getDataType() const override; + ColumnEncoding getEncoding() const override; - bool getBoolean(int32_t position) const override; - int32_t getInt(int32_t position) const override; - int64_t getLong(int32_t position) const override; - float getFloat(int32_t position) const override; - double getDouble(int32_t position) const override; - std::shared_ptr getBinary(int32_t position) const override; + bool getBoolean(int32_t position) const override; + int32_t getInt(int32_t position) const override; + int64_t getLong(int32_t position) const override; + float getFloat(int32_t position) const override; + double getDouble(int32_t position) const override; + std::shared_ptr getBinary(int32_t position) const override; - std::vector getBooleans() const override; - std::vector getInts() const override; - std::vector getLongs() const override; - std::vector getFloats() const override; - std::vector getDoubles() const override; - std::vector> getBinaries() const override; + std::vector getBooleans() const override; + std::vector getInts() const override; + std::vector getLongs() const override; + std::vector getFloats() const override; + std::vector getDoubles() const override; + std::vector> getBinaries() const override; - bool mayHaveNull() const override; - bool isNull(int32_t position) const override; - std::vector isNulls() const override; + bool mayHaveNull() const override; + bool isNull(int32_t position) const override; + std::vector isNulls() const override; - int32_t getPositionCount() const override; + int32_t getPositionCount() const override; private: - std::shared_ptr value_; - int32_t positionCount_; + std::shared_ptr value_; + int32_t positionCount_; }; #endif diff --git a/iotdb-client/client-cpp/src/main/ColumnDecoder.cpp b/iotdb-client/client-cpp/src/main/ColumnDecoder.cpp index 32f29d876f368..42f13fcc27eed 100644 --- a/iotdb-client/client-cpp/src/main/ColumnDecoder.cpp +++ b/iotdb-client/client-cpp/src/main/ColumnDecoder.cpp @@ -22,160 +22,175 @@ #include "Column.h" std::vector deserializeNullIndicators(MyStringBuffer& buffer, int32_t positionCount) { - uint8_t mayHaveNullByte = buffer.getChar(); + uint8_t mayHaveNullByte = buffer.getChar(); - bool mayHaveNull = mayHaveNullByte != 0; - if (!mayHaveNull) { - return {}; - } + bool mayHaveNull = mayHaveNullByte != 0; + if (!mayHaveNull) { + return {}; + } - return deserializeBooleanArray(buffer, positionCount); + return deserializeBooleanArray(buffer, positionCount); } std::vector deserializeBooleanArray(MyStringBuffer& buffer, int32_t size) { - const int32_t packedSize = (size + 7) / 8; - std::vector packedBytes(packedSize); - for (int i = 0; i < packedSize; i++) { - packedBytes[i] = buffer.getChar(); - } - - std::vector output(size); - int currentByte = 0; - const int fullGroups = size & ~0b111; - - for (int pos = 0; pos < fullGroups; pos += 8) { - const uint8_t b = packedBytes[currentByte++]; - output[pos + 0] = (b & 0b10000000) != 0; - output[pos + 1] = (b & 0b01000000) != 0; - output[pos + 2] = (b & 0b00100000) != 0; - output[pos + 3] = (b & 0b00010000) != 0; - output[pos + 4] = (b & 0b00001000) != 0; - output[pos + 5] = (b & 0b00000100) != 0; - output[pos + 6] = (b & 0b00000010) != 0; - output[pos + 7] = (b & 0b00000001) != 0; - } - - if ((size & 0b111) > 0) { - const uint8_t b = packedBytes.back(); - uint8_t mask = 0b10000000; - - for (int pos = fullGroups; pos < size; pos++) { - output[pos] = (b & mask) != 0; - mask >>= 1; - } + const int32_t packedSize = (size + 7) / 8; + std::vector packedBytes(packedSize); + for (int i = 0; i < packedSize; i++) { + packedBytes[i] = buffer.getChar(); + } + + std::vector output(size); + int currentByte = 0; + const int fullGroups = size & ~0b111; + + for (int pos = 0; pos < fullGroups; pos += 8) { + const uint8_t b = packedBytes[currentByte++]; + output[pos + 0] = (b & 0b10000000) != 0; + output[pos + 1] = (b & 0b01000000) != 0; + output[pos + 2] = (b & 0b00100000) != 0; + output[pos + 3] = (b & 0b00010000) != 0; + output[pos + 4] = (b & 0b00001000) != 0; + output[pos + 5] = (b & 0b00000100) != 0; + output[pos + 6] = (b & 0b00000010) != 0; + output[pos + 7] = (b & 0b00000001) != 0; + } + + if ((size & 0b111) > 0) { + const uint8_t b = packedBytes.back(); + uint8_t mask = 0b10000000; + + for (int pos = fullGroups; pos < size; pos++) { + output[pos] = (b & mask) != 0; + mask >>= 1; } + } - return output; + return output; } -std::unique_ptr BaseColumnDecoder::readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) { - return nullptr; +std::unique_ptr BaseColumnDecoder::readColumn(MyStringBuffer& buffer, + TSDataType::TSDataType dataType, + int32_t positionCount) { + return nullptr; } -std::unique_ptr Int32ArrayColumnDecoder::readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) { - auto nullIndicators = deserializeNullIndicators(buffer, positionCount); - - switch (dataType) { - case TSDataType::INT32: - case TSDataType::DATE: { - std::vector intValues(positionCount); - for (int32_t i = 0; i < positionCount; i++) { - if (!nullIndicators.empty() && nullIndicators[i]) continue; - intValues[i] = buffer.getInt(); - } - return std::unique_ptr(new IntColumn(0, positionCount, nullIndicators, intValues)); - } - case TSDataType::FLOAT: { - std::vector floatValues(positionCount); - for (int32_t i = 0; i < positionCount; i++) { - if (!nullIndicators.empty() && nullIndicators[i]) continue; - floatValues[i] = buffer.getFloat(); - } - return std::unique_ptr(new FloatColumn(0, positionCount, nullIndicators, floatValues)); +std::unique_ptr Int32ArrayColumnDecoder::readColumn(MyStringBuffer& buffer, + TSDataType::TSDataType dataType, + int32_t positionCount) { + auto nullIndicators = deserializeNullIndicators(buffer, positionCount); + + switch (dataType) { + case TSDataType::INT32: + case TSDataType::DATE: { + std::vector intValues(positionCount); + for (int32_t i = 0; i < positionCount; i++) { + if (!nullIndicators.empty() && nullIndicators[i]) + continue; + intValues[i] = buffer.getInt(); } - default: - throw IoTDBException("Invalid data type for Int32ArrayColumnDecoder"); + return std::unique_ptr(new IntColumn(0, positionCount, nullIndicators, intValues)); + } + case TSDataType::FLOAT: { + std::vector floatValues(positionCount); + for (int32_t i = 0; i < positionCount; i++) { + if (!nullIndicators.empty() && nullIndicators[i]) + continue; + floatValues[i] = buffer.getFloat(); } + return std::unique_ptr( + new FloatColumn(0, positionCount, nullIndicators, floatValues)); + } + default: + throw IoTDBException("Invalid data type for Int32ArrayColumnDecoder"); + } } -std::unique_ptr Int64ArrayColumnDecoder::readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) { - auto nullIndicators = deserializeNullIndicators(buffer, positionCount); - - switch (dataType) { - case TSDataType::INT64: - case TSDataType::TIMESTAMP: { - std::vector values(positionCount); - for (int32_t i = 0; i < positionCount; i++) { - if (!nullIndicators.empty() && nullIndicators[i]) continue; - values[i] = buffer.getInt64(); - } - return std::unique_ptr(new LongColumn(0, positionCount, nullIndicators, values)); - } - case TSDataType::DOUBLE: { - std::vector values(positionCount); - for (int32_t i = 0; i < positionCount; i++) { - if (!nullIndicators.empty() && nullIndicators[i]) continue; - values[i] = buffer.getDouble(); - } - return std::unique_ptr(new DoubleColumn(0, positionCount, nullIndicators, values)); +std::unique_ptr Int64ArrayColumnDecoder::readColumn(MyStringBuffer& buffer, + TSDataType::TSDataType dataType, + int32_t positionCount) { + auto nullIndicators = deserializeNullIndicators(buffer, positionCount); + + switch (dataType) { + case TSDataType::INT64: + case TSDataType::TIMESTAMP: { + std::vector values(positionCount); + for (int32_t i = 0; i < positionCount; i++) { + if (!nullIndicators.empty() && nullIndicators[i]) + continue; + values[i] = buffer.getInt64(); } - default: - throw IoTDBException("Invalid data type for Int64ArrayColumnDecoder"); + return std::unique_ptr(new LongColumn(0, positionCount, nullIndicators, values)); + } + case TSDataType::DOUBLE: { + std::vector values(positionCount); + for (int32_t i = 0; i < positionCount; i++) { + if (!nullIndicators.empty() && nullIndicators[i]) + continue; + values[i] = buffer.getDouble(); } + return std::unique_ptr( + new DoubleColumn(0, positionCount, nullIndicators, values)); + } + default: + throw IoTDBException("Invalid data type for Int64ArrayColumnDecoder"); + } } -std::unique_ptr ByteArrayColumnDecoder::readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) { - if (dataType != TSDataType::BOOLEAN) { - throw IoTDBException("Invalid data type for ByteArrayColumnDecoder"); - } - - auto nullIndicators = deserializeNullIndicators(buffer, positionCount); - auto values = deserializeBooleanArray(buffer, positionCount); - return std::unique_ptr(new BooleanColumn(0, positionCount, nullIndicators, values)); +std::unique_ptr ByteArrayColumnDecoder::readColumn(MyStringBuffer& buffer, + TSDataType::TSDataType dataType, + int32_t positionCount) { + if (dataType != TSDataType::BOOLEAN) { + throw IoTDBException("Invalid data type for ByteArrayColumnDecoder"); + } + + auto nullIndicators = deserializeNullIndicators(buffer, positionCount); + auto values = deserializeBooleanArray(buffer, positionCount); + return std::unique_ptr( + new BooleanColumn(0, positionCount, nullIndicators, values)); } -std::unique_ptr BinaryArrayColumnDecoder::readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) { - if (dataType != TSDataType::TEXT) { - throw IoTDBException("Invalid data type for BinaryArrayColumnDecoder"); - } +std::unique_ptr BinaryArrayColumnDecoder::readColumn(MyStringBuffer& buffer, + TSDataType::TSDataType dataType, + int32_t positionCount) { + if (dataType != TSDataType::TEXT) { + throw IoTDBException("Invalid data type for BinaryArrayColumnDecoder"); + } - auto nullIndicators = deserializeNullIndicators(buffer, positionCount); - std::vector> values(positionCount); + auto nullIndicators = deserializeNullIndicators(buffer, positionCount); + std::vector> values(positionCount); - for (int32_t i = 0; i < positionCount; i++) { - if (!nullIndicators.empty() && nullIndicators[i]) continue; - - int32_t length = buffer.getInt(); - if (length < 0) { - throw IoTDBException("BinaryArrayColumnDecoder: negative TEXT length"); - } + for (int32_t i = 0; i < positionCount; i++) { + if (!nullIndicators.empty() && nullIndicators[i]) + continue; - std::vector value(length); - for (int32_t j = 0; j < length; j++) { - value[j] = buffer.getChar(); - } + int32_t length = buffer.getInt(); + if (length < 0) { + throw IoTDBException("BinaryArrayColumnDecoder: negative TEXT length"); + } - values[i] = std::make_shared(value); + std::vector value(length); + for (int32_t j = 0; j < length; j++) { + value[j] = buffer.getChar(); } - return std::unique_ptr(new BinaryColumn(0, positionCount, nullIndicators, values)); + values[i] = std::make_shared(value); + } + + return std::unique_ptr(new BinaryColumn(0, positionCount, nullIndicators, values)); } -std::unique_ptr RunLengthColumnDecoder::readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) { - uint8_t encodingByte = buffer.getChar(); +std::unique_ptr RunLengthColumnDecoder::readColumn(MyStringBuffer& buffer, + TSDataType::TSDataType dataType, + int32_t positionCount) { + uint8_t encodingByte = buffer.getChar(); - auto columnEncoding = static_cast(encodingByte); - auto decoder = getColumnDecoder(columnEncoding); + auto columnEncoding = static_cast(encodingByte); + auto decoder = getColumnDecoder(columnEncoding); - auto column = decoder->readColumn(buffer, dataType, 1); - if (!column) { - throw IoTDBException("Failed to read inner column"); - } - return std::unique_ptr(new RunLengthEncodedColumn(move(column), positionCount)); + auto column = decoder->readColumn(buffer, dataType, 1); + if (!column) { + throw IoTDBException("Failed to read inner column"); + } + return std::unique_ptr( + new RunLengthEncodedColumn(move(column), positionCount)); } diff --git a/iotdb-client/client-cpp/src/main/ColumnDecoder.h b/iotdb-client/client-cpp/src/main/ColumnDecoder.h index f5340d1e400ac..5765d1a113470 100644 --- a/iotdb-client/client-cpp/src/main/ColumnDecoder.h +++ b/iotdb-client/client-cpp/src/main/ColumnDecoder.h @@ -28,9 +28,9 @@ class Column; class ColumnDecoder { public: - virtual ~ColumnDecoder() = default; - virtual std::unique_ptr readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) = 0; + virtual ~ColumnDecoder() = default; + virtual std::unique_ptr + readColumn(MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) = 0; }; std::vector deserializeNullIndicators(MyStringBuffer& buffer, int32_t positionCount); @@ -38,38 +38,38 @@ std::vector deserializeBooleanArray(MyStringBuffer& buffer, int32_t size); class BaseColumnDecoder : public ColumnDecoder { public: - std::unique_ptr readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) override; + std::unique_ptr readColumn(MyStringBuffer& buffer, TSDataType::TSDataType dataType, + int32_t positionCount) override; }; class Int32ArrayColumnDecoder : public BaseColumnDecoder { public: - std::unique_ptr readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) override; + std::unique_ptr readColumn(MyStringBuffer& buffer, TSDataType::TSDataType dataType, + int32_t positionCount) override; }; class Int64ArrayColumnDecoder : public BaseColumnDecoder { public: - std::unique_ptr readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) override; + std::unique_ptr readColumn(MyStringBuffer& buffer, TSDataType::TSDataType dataType, + int32_t positionCount) override; }; class ByteArrayColumnDecoder : public BaseColumnDecoder { public: - std::unique_ptr readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) override; + std::unique_ptr readColumn(MyStringBuffer& buffer, TSDataType::TSDataType dataType, + int32_t positionCount) override; }; class BinaryArrayColumnDecoder : public BaseColumnDecoder { public: - std::unique_ptr readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) override; + std::unique_ptr readColumn(MyStringBuffer& buffer, TSDataType::TSDataType dataType, + int32_t positionCount) override; }; class RunLengthColumnDecoder : public BaseColumnDecoder { public: - std::unique_ptr readColumn( - MyStringBuffer& buffer, TSDataType::TSDataType dataType, int32_t positionCount) override; + std::unique_ptr readColumn(MyStringBuffer& buffer, TSDataType::TSDataType dataType, + int32_t positionCount) override; }; #endif diff --git a/iotdb-client/client-cpp/src/main/Common.cpp b/iotdb-client/client-cpp/src/main/Common.cpp index f7eeb2a218e49..ccdb2553831b7 100644 --- a/iotdb-client/client-cpp/src/main/Common.cpp +++ b/iotdb-client/client-cpp/src/main/Common.cpp @@ -21,497 +21,505 @@ #include int32_t parseDateExpressionToInt(const boost::gregorian::date& date) { - if (date.is_not_a_date()) { - throw IoTDBException("Date expression is null or empty."); - } + if (date.is_not_a_date()) { + throw IoTDBException("Date expression is null or empty."); + } - const int year = date.year(); - if (year < 1000 || year > 9999) { - throw DateTimeParseException( - "Year must be between 1000 and 9999.", - boost::gregorian::to_iso_extended_string(date), - 0 - ); - } + const int year = date.year(); + if (year < 1000 || year > 9999) { + throw DateTimeParseException("Year must be between 1000 and 9999.", + boost::gregorian::to_iso_extended_string(date), 0); + } - const int64_t result = static_cast(year) * 10000 + - date.month() * 100 + - date.day(); - if (result > INT32_MAX || result < INT32_MIN) { - throw DateTimeParseException( - "Date value overflow. ", - boost::gregorian::to_iso_extended_string(date), - 0 - ); - } - return static_cast(result); + const int64_t result = static_cast(year) * 10000 + date.month() * 100 + date.day(); + if (result > INT32_MAX || result < INT32_MIN) { + throw DateTimeParseException("Date value overflow. ", + boost::gregorian::to_iso_extended_string(date), 0); + } + return static_cast(result); } boost::gregorian::date parseIntToDate(int32_t dateInt) { - if (dateInt == EMPTY_DATE_INT) { - return boost::gregorian::date(boost::date_time::not_a_date_time); - } - int year = dateInt / 10000; - int month = (dateInt % 10000) / 100; - int day = dateInt % 100; - return boost::gregorian::date(year, month, day); + if (dateInt == EMPTY_DATE_INT) { + return boost::gregorian::date(boost::date_time::not_a_date_time); + } + int year = dateInt / 10000; + int month = (dateInt % 10000) / 100; + int day = dateInt % 100; + return boost::gregorian::date(year, month, day); } std::string getTimePrecision(int32_t timeFactor) { - if (timeFactor >= 1000000) return "us"; - if (timeFactor >= 1000) return "ms"; - return "s"; + if (timeFactor >= 1000000) + return "us"; + if (timeFactor >= 1000) + return "ms"; + return "s"; } std::string formatDatetime(const std::string& format, const std::string& precision, int64_t timestamp, const std::string& zoneId) { - // Simplified implementation - in real code you'd use proper timezone handling - std::time_t time = static_cast(timestamp); - std::tm* tm = std::localtime(&time); - char buffer[80]; - strftime(buffer, sizeof(buffer), format.c_str(), tm); - return std::string(buffer); + // Simplified implementation - in real code you'd use proper timezone handling + std::time_t time = static_cast(timestamp); + std::tm* tm = std::localtime(&time); + char buffer[80]; + strftime(buffer, sizeof(buffer), format.c_str(), tm); + return std::string(buffer); } std::tm convertToTimestamp(int64_t value, int32_t timeFactor) { - std::time_t time = static_cast(value / timeFactor); - return *std::localtime(&time); + std::time_t time = static_cast(value / timeFactor); + return *std::localtime(&time); } TSDataType::TSDataType getDataTypeByStr(const std::string& typeStr) { - if (typeStr == "BOOLEAN") return TSDataType::BOOLEAN; - if (typeStr == "INT32") return TSDataType::INT32; - if (typeStr == "INT64") return TSDataType::INT64; - if (typeStr == "FLOAT") return TSDataType::FLOAT; - if (typeStr == "DOUBLE") return TSDataType::DOUBLE; - if (typeStr == "TEXT") return TSDataType::TEXT; - if (typeStr == "TIMESTAMP") return TSDataType::TIMESTAMP; - if (typeStr == "DATE") return TSDataType::DATE; - if (typeStr == "BLOB") return TSDataType::BLOB; - if (typeStr == "STRING") return TSDataType::STRING; - if (typeStr == "OBJECT") return TSDataType::OBJECT; - return TSDataType::UNKNOWN; + if (typeStr == "BOOLEAN") + return TSDataType::BOOLEAN; + if (typeStr == "INT32") + return TSDataType::INT32; + if (typeStr == "INT64") + return TSDataType::INT64; + if (typeStr == "FLOAT") + return TSDataType::FLOAT; + if (typeStr == "DOUBLE") + return TSDataType::DOUBLE; + if (typeStr == "TEXT") + return TSDataType::TEXT; + if (typeStr == "TIMESTAMP") + return TSDataType::TIMESTAMP; + if (typeStr == "DATE") + return TSDataType::DATE; + if (typeStr == "BLOB") + return TSDataType::BLOB; + if (typeStr == "STRING") + return TSDataType::STRING; + if (typeStr == "OBJECT") + return TSDataType::OBJECT; + return TSDataType::UNKNOWN; } std::tm int32ToDate(int32_t value) { - // Convert days since epoch (1970-01-01) to tm struct - std::time_t time = static_cast(value) * 86400; // seconds per day - return *std::localtime(&time); + // Convert days since epoch (1970-01-01) to tm struct + std::time_t time = static_cast(value) * 86400; // seconds per day + return *std::localtime(&time); } void RpcUtils::verifySuccess(const TSStatus& status) { - if (status.code == TSStatusCode::MULTIPLE_ERROR) { - verifySuccess(status.subStatus); - return; - } - if (status.code != TSStatusCode::SUCCESS_STATUS - && status.code != TSStatusCode::REDIRECTION_RECOMMEND) { - throw ExecutionException(to_string(status.code) + ": " + status.message, status); - } + if (status.code == TSStatusCode::MULTIPLE_ERROR) { + verifySuccess(status.subStatus); + return; + } + if (status.code != TSStatusCode::SUCCESS_STATUS && + status.code != TSStatusCode::REDIRECTION_RECOMMEND) { + throw ExecutionException(to_string(status.code) + ": " + status.message, status); + } } void RpcUtils::verifySuccessWithRedirection(const TSStatus& status) { - verifySuccess(status); - if (status.__isset.redirectNode) { - throw RedirectException(to_string(status.code) + ": " + status.message, status.redirectNode); + verifySuccess(status); + if (status.__isset.redirectNode) { + throw RedirectException(to_string(status.code) + ": " + status.message, status.redirectNode); + } + if (status.__isset.subStatus) { + auto statusSubStatus = status.subStatus; + vector endPointList(statusSubStatus.size()); + int count = 0; + for (TSStatus subStatus : statusSubStatus) { + if (subStatus.__isset.redirectNode) { + endPointList[count++] = subStatus.redirectNode; + } else { + TEndPoint endPoint; + endPointList[count++] = endPoint; + } } - if (status.__isset.subStatus) { - auto statusSubStatus = status.subStatus; - vector endPointList(statusSubStatus.size()); - int count = 0; - for (TSStatus subStatus : statusSubStatus) { - if (subStatus.__isset.redirectNode) { - endPointList[count++] = subStatus.redirectNode; - } - else { - TEndPoint endPoint; - endPointList[count++] = endPoint; - } - } - if (!endPointList.empty()) { - throw RedirectException(to_string(status.code) + ": " + status.message, endPointList); - } + if (!endPointList.empty()) { + throw RedirectException(to_string(status.code) + ": " + status.message, endPointList); } -} - -void RpcUtils::verifySuccessWithRedirectionForMultiDevices(const TSStatus& status, vector devices) { - verifySuccess(status); - - if (status.code == TSStatusCode::MULTIPLE_ERROR - || status.code == TSStatusCode::REDIRECTION_RECOMMEND) { - map deviceEndPointMap; - vector statusSubStatus; - for (int i = 0; i < statusSubStatus.size(); i++) { - TSStatus subStatus = statusSubStatus[i]; - if (subStatus.__isset.redirectNode) { - deviceEndPointMap.insert(make_pair(devices[i], subStatus.redirectNode)); - } - } - throw RedirectException(to_string(status.code) + ": " + status.message, deviceEndPointMap); + } +} + +void RpcUtils::verifySuccessWithRedirectionForMultiDevices(const TSStatus& status, + vector devices) { + verifySuccess(status); + + if (status.code == TSStatusCode::MULTIPLE_ERROR || + status.code == TSStatusCode::REDIRECTION_RECOMMEND) { + map deviceEndPointMap; + vector statusSubStatus; + for (int i = 0; i < statusSubStatus.size(); i++) { + TSStatus subStatus = statusSubStatus[i]; + if (subStatus.__isset.redirectNode) { + deviceEndPointMap.insert(make_pair(devices[i], subStatus.redirectNode)); + } } - - if (status.__isset.redirectNode) { - throw RedirectException(to_string(status.code) + ": " + status.message, status.redirectNode); + throw RedirectException(to_string(status.code) + ": " + status.message, deviceEndPointMap); + } + + if (status.__isset.redirectNode) { + throw RedirectException(to_string(status.code) + ": " + status.message, status.redirectNode); + } + if (status.__isset.subStatus) { + auto statusSubStatus = status.subStatus; + vector endPointList(statusSubStatus.size()); + int count = 0; + for (TSStatus subStatus : statusSubStatus) { + if (subStatus.__isset.redirectNode) { + endPointList[count++] = subStatus.redirectNode; + } else { + TEndPoint endPoint; + endPointList[count++] = endPoint; + } } - if (status.__isset.subStatus) { - auto statusSubStatus = status.subStatus; - vector endPointList(statusSubStatus.size()); - int count = 0; - for (TSStatus subStatus : statusSubStatus) { - if (subStatus.__isset.redirectNode) { - endPointList[count++] = subStatus.redirectNode; - } - else { - TEndPoint endPoint; - endPointList[count++] = endPoint; - } - } - if (!endPointList.empty()) { - throw RedirectException(to_string(status.code) + ": " + status.message, endPointList); - } + if (!endPointList.empty()) { + throw RedirectException(to_string(status.code) + ": " + status.message, endPointList); } + } } void RpcUtils::verifySuccess(const vector& statuses) { - for (const TSStatus& status : statuses) { - if (status.code != TSStatusCode::SUCCESS_STATUS) { - throw BatchExecutionException(status.message, statuses); - } + for (const TSStatus& status : statuses) { + if (status.code != TSStatusCode::SUCCESS_STATUS) { + throw BatchExecutionException(status.message, statuses); } + } } TSStatus RpcUtils::getStatus(TSStatusCode::TSStatusCode tsStatusCode) { - TSStatus status; - status.__set_code(tsStatusCode); - return status; + TSStatus status; + status.__set_code(tsStatusCode); + return status; } TSStatus RpcUtils::getStatus(int code, const string& message) { - TSStatus status; - status.__set_code(code); - status.__set_message(message); - return status; + TSStatus status; + status.__set_code(code); + status.__set_message(message); + return status; } -shared_ptr RpcUtils::getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode) { - TSStatus status = getStatus(tsStatusCode); - return getTSExecuteStatementResp(status); +shared_ptr +RpcUtils::getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode) { + TSStatus status = getStatus(tsStatusCode); + return getTSExecuteStatementResp(status); } shared_ptr -RpcUtils::getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode, const string& message) { - TSStatus status = getStatus(tsStatusCode, message); - return getTSExecuteStatementResp(status); +RpcUtils::getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode, + const string& message) { + TSStatus status = getStatus(tsStatusCode, message); + return getTSExecuteStatementResp(status); } shared_ptr RpcUtils::getTSExecuteStatementResp(const TSStatus& status) { - shared_ptr resp(new TSExecuteStatementResp()); - TSStatus tsStatus(status); - resp->__set_status(status); - return resp; + shared_ptr resp(new TSExecuteStatementResp()); + TSStatus tsStatus(status); + resp->__set_status(status); + return resp; } -shared_ptr RpcUtils::getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode) { - TSStatus status = getStatus(tsStatusCode); - return getTSFetchResultsResp(status); +shared_ptr +RpcUtils::getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode) { + TSStatus status = getStatus(tsStatusCode); + return getTSFetchResultsResp(status); } shared_ptr -RpcUtils::getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode, const string& appendMessage) { - TSStatus status = getStatus(tsStatusCode, appendMessage); - return getTSFetchResultsResp(status); +RpcUtils::getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode, + const string& appendMessage) { + TSStatus status = getStatus(tsStatusCode, appendMessage); + return getTSFetchResultsResp(status); } shared_ptr RpcUtils::getTSFetchResultsResp(const TSStatus& status) { - shared_ptr resp(new TSFetchResultsResp()); - TSStatus tsStatus(status); - resp->__set_status(tsStatus); - return resp; + shared_ptr resp(new TSFetchResultsResp()); + TSStatus tsStatus(status); + resp->__set_status(tsStatus); + return resp; } MyStringBuffer::MyStringBuffer() : pos(0) { - checkBigEndian(); + checkBigEndian(); } MyStringBuffer::MyStringBuffer(const std::string& str) : str(str), pos(0) { - checkBigEndian(); + checkBigEndian(); } void MyStringBuffer::reserve(size_t n) { - str.reserve(n); + str.reserve(n); } void MyStringBuffer::clear() { - str.clear(); - pos = 0; + str.clear(); + pos = 0; } bool MyStringBuffer::hasRemaining() { - return pos < str.size(); + return pos < str.size(); } int MyStringBuffer::getInt() { - return *(int*)getOrderedByte(4); + return *(int*)getOrderedByte(4); } boost::gregorian::date MyStringBuffer::getDate() { - return parseIntToDate(getInt()); + return parseIntToDate(getInt()); } int64_t MyStringBuffer::getInt64() { #ifdef ARCH32 - const char *buf_addr = getOrderedByte(8); - if (reinterpret_cast(buf_addr) % 4 == 0) { - return *(int64_t *)buf_addr; - } else { - char tmp_buf[8]; - memcpy(tmp_buf, buf_addr, 8); - return *(int64_t*)tmp_buf; - } + const char* buf_addr = getOrderedByte(8); + if (reinterpret_cast(buf_addr) % 4 == 0) { + return *(int64_t*)buf_addr; + } else { + char tmp_buf[8]; + memcpy(tmp_buf, buf_addr, 8); + return *(int64_t*)tmp_buf; + } #else - return *(int64_t*)getOrderedByte(8); + return *(int64_t*)getOrderedByte(8); #endif } float MyStringBuffer::getFloat() { - return *(float*)getOrderedByte(4); + return *(float*)getOrderedByte(4); } double MyStringBuffer::getDouble() { #ifdef ARCH32 - const char *buf_addr = getOrderedByte(8); - if (reinterpret_cast(buf_addr) % 4 == 0) { - return *(double*)buf_addr; - } else { - char tmp_buf[8]; - memcpy(tmp_buf, buf_addr, 8); - return *(double*)tmp_buf; - } + const char* buf_addr = getOrderedByte(8); + if (reinterpret_cast(buf_addr) % 4 == 0) { + return *(double*)buf_addr; + } else { + char tmp_buf[8]; + memcpy(tmp_buf, buf_addr, 8); + return *(double*)tmp_buf; + } #else - return *(double*)getOrderedByte(8); + return *(double*)getOrderedByte(8); #endif } char MyStringBuffer::getChar() { - if (pos >= str.size()) { - throw IoTDBException("MyStringBuffer::getChar: read past end (pos=" + std::to_string(pos) + - ", size=" + std::to_string(str.size()) + ")"); - } - return str[pos++]; + if (pos >= str.size()) { + throw IoTDBException("MyStringBuffer::getChar: read past end (pos=" + std::to_string(pos) + + ", size=" + std::to_string(str.size()) + ")"); + } + return str[pos++]; } bool MyStringBuffer::getBool() { - return getChar() == 1; + return getChar() == 1; } std::string MyStringBuffer::getString() { - const int lenInt = getInt(); - if (lenInt < 0) { - throw IoTDBException("MyStringBuffer::getString: negative length"); - } - const size_t len = static_cast(lenInt); - if (pos > str.size() || len > str.size() - pos) { - throw IoTDBException("MyStringBuffer::getString: length exceeds buffer (pos=" + std::to_string(pos) + - ", len=" + std::to_string(len) + ", size=" + std::to_string(str.size()) + ")"); - } - const size_t tmpPos = pos; - pos += len; - return str.substr(tmpPos, len); + const int lenInt = getInt(); + if (lenInt < 0) { + throw IoTDBException("MyStringBuffer::getString: negative length"); + } + const size_t len = static_cast(lenInt); + if (pos > str.size() || len > str.size() - pos) { + throw IoTDBException( + "MyStringBuffer::getString: length exceeds buffer (pos=" + std::to_string(pos) + + ", len=" + std::to_string(len) + ", size=" + std::to_string(str.size()) + ")"); + } + const size_t tmpPos = pos; + pos += len; + return str.substr(tmpPos, len); } void MyStringBuffer::putInt(int ins) { - putOrderedByte((char*)&ins, 4); + putOrderedByte((char*)&ins, 4); } void MyStringBuffer::putDate(boost::gregorian::date date) { - putInt(parseDateExpressionToInt(date)); + putInt(parseDateExpressionToInt(date)); } void MyStringBuffer::putInt64(int64_t ins) { - putOrderedByte((char*)&ins, 8); + putOrderedByte((char*)&ins, 8); } void MyStringBuffer::putFloat(float ins) { - putOrderedByte((char*)&ins, 4); + putOrderedByte((char*)&ins, 4); } void MyStringBuffer::putDouble(double ins) { - putOrderedByte((char*)&ins, 8); + putOrderedByte((char*)&ins, 8); } void MyStringBuffer::putChar(char ins) { - str += ins; + str += ins; } void MyStringBuffer::putBool(bool ins) { - char tmp = ins ? 1 : 0; - str += tmp; + char tmp = ins ? 1 : 0; + str += tmp; } void MyStringBuffer::putString(const std::string& ins) { - putInt((int)(ins.size())); - str += ins; + putInt((int)(ins.size())); + str += ins; } void MyStringBuffer::concat(const std::string& ins) { - str.append(ins); + str.append(ins); } void MyStringBuffer::checkBigEndian() { - static int chk = 0x0201; //used to distinguish CPU's type (BigEndian or LittleEndian) - isBigEndian = (0x01 != *(char*)(&chk)); + static int chk = 0x0201; //used to distinguish CPU's type (BigEndian or LittleEndian) + isBigEndian = (0x01 != *(char*)(&chk)); } const char* MyStringBuffer::getOrderedByte(size_t len) { - if (pos > str.size() || len > str.size() - pos) { - throw IoTDBException("MyStringBuffer::getOrderedByte: read past end (pos=" + std::to_string(pos) + - ", len=" + std::to_string(len) + ", size=" + std::to_string(str.size()) + ")"); + if (pos > str.size() || len > str.size() - pos) { + throw IoTDBException( + "MyStringBuffer::getOrderedByte: read past end (pos=" + std::to_string(pos) + + ", len=" + std::to_string(len) + ", size=" + std::to_string(str.size()) + ")"); + } + const char* p = nullptr; + if (isBigEndian) { + p = str.c_str() + pos; + } else { + const char* tmp = str.c_str(); + for (size_t i = pos; i < pos + len; i++) { + numericBuf[pos + len - 1 - i] = tmp[i]; } - const char* p = nullptr; - if (isBigEndian) { - p = str.c_str() + pos; - } - else { - const char* tmp = str.c_str(); - for (size_t i = pos; i < pos + len; i++) { - numericBuf[pos + len - 1 - i] = tmp[i]; - } - p = numericBuf; - } - pos += len; - return p; + p = numericBuf; + } + pos += len; + return p; } void MyStringBuffer::putOrderedByte(char* buf, int len) { - if (isBigEndian) { - str.assign(buf, len); - } - else { - for (int i = len - 1; i > -1; i--) { - str += buf[i]; - } + if (isBigEndian) { + str.assign(buf, len); + } else { + for (int i = len - 1; i > -1; i--) { + str += buf[i]; } + } } BitMap::BitMap(size_t size) { - resize(size); + resize(size); } void BitMap::resize(size_t size) { - this->size = size; - this->bits.resize((size >> 3) + 1); // equal to "size/8 + 1" - reset(); + this->size = size; + this->bits.resize((size >> 3) + 1); // equal to "size/8 + 1" + reset(); } bool BitMap::mark(size_t position) { - if (position >= size) - return false; + if (position >= size) + return false; - bits[position >> 3] |= (char)1 << (position % 8); - return true; + bits[position >> 3] |= (char)1 << (position % 8); + return true; } bool BitMap::unmark(size_t position) { - if (position >= size) - return false; + if (position >= size) + return false; - bits[position >> 3] &= ~((char)1 << (position % 8)); - return true; + bits[position >> 3] &= ~((char)1 << (position % 8)); + return true; } void BitMap::markAll() { - std::fill(bits.begin(), bits.end(), (char)0XFF); + std::fill(bits.begin(), bits.end(), (char)0XFF); } void BitMap::reset() { - std::fill(bits.begin(), bits.end(), (char)0); + std::fill(bits.begin(), bits.end(), (char)0); } bool BitMap::isMarked(size_t position) const { - if (position >= size) - return false; + if (position >= size) + return false; - return (bits[position >> 3] & ((char)1 << (position % 8))) != 0; + return (bits[position >> 3] & ((char)1 << (position % 8))) != 0; } bool BitMap::isAllUnmarked() const { - size_t j; - for (j = 0; j < size >> 3; j++) { - if (bits[j] != (char)0) { - return false; - } + size_t j; + for (j = 0; j < size >> 3; j++) { + if (bits[j] != (char)0) { + return false; } - for (j = 0; j < size % 8; j++) { - if ((bits[size >> 3] & ((char)1 << j)) != 0) { - return false; - } + } + for (j = 0; j < size % 8; j++) { + if ((bits[size >> 3] & ((char)1 << j)) != 0) { + return false; } - return true; + } + return true; } bool BitMap::isAllMarked() const { - size_t j; - for (j = 0; j < size >> 3; j++) { - if (bits[j] != (char)0XFF) { - return false; - } + size_t j; + for (j = 0; j < size >> 3; j++) { + if (bits[j] != (char)0XFF) { + return false; } - for (j = 0; j < size % 8; j++) { - if ((bits[size >> 3] & ((char)1 << j)) == 0) { - return false; - } + } + for (j = 0; j < size % 8; j++) { + if ((bits[size >> 3] & ((char)1 << j)) == 0) { + return false; } - return true; + } + return true; } const std::vector& BitMap::getByteArray() const { - return this->bits; + return this->bits; } size_t BitMap::getSize() const { - return this->size; + return this->size; } const std::string UrlUtils::PORT_SEPARATOR = ":"; const std::string UrlUtils::ABB_COLON = "["; TEndPoint UrlUtils::parseTEndPointIpv4AndIpv6Url(const std::string& endPointUrl) { - TEndPoint endPoint; + TEndPoint endPoint; - // Return default TEndPoint if input is empty - if (endPointUrl.empty()) { - return endPoint; - } + // Return default TEndPoint if input is empty + if (endPointUrl.empty()) { + return endPoint; + } - size_t portSeparatorPos = endPointUrl.find_last_of(PORT_SEPARATOR); + size_t portSeparatorPos = endPointUrl.find_last_of(PORT_SEPARATOR); - // If no port separator found, treat entire string as IP - if (portSeparatorPos == std::string::npos) { - endPoint.__set_ip(endPointUrl); - return endPoint; - } + // If no port separator found, treat entire string as IP + if (portSeparatorPos == std::string::npos) { + endPoint.__set_ip(endPointUrl); + return endPoint; + } - // Extract port part - std::string portStr = endPointUrl.substr(portSeparatorPos + 1); + // Extract port part + std::string portStr = endPointUrl.substr(portSeparatorPos + 1); - // Extract IP part - std::string ip = endPointUrl.substr(0, portSeparatorPos); + // Extract IP part + std::string ip = endPointUrl.substr(0, portSeparatorPos); - // Handle IPv6 addresses with brackets - if (ip.find(ABB_COLON) != std::string::npos) { - // Remove surrounding square brackets for IPv6 - if (ip.size() >= 2 && ip.front() == '[' && ip.back() == ']') { - ip = ip.substr(1, ip.size() - 2); - } + // Handle IPv6 addresses with brackets + if (ip.find(ABB_COLON) != std::string::npos) { + // Remove surrounding square brackets for IPv6 + if (ip.size() >= 2 && ip.front() == '[' && ip.back() == ']') { + ip = ip.substr(1, ip.size() - 2); } + } - try { - int port = std::stoi(portStr); - endPoint.__set_ip(ip); - endPoint.__set_port(port); - } catch (const std::exception& e) { - endPoint.__set_ip(endPointUrl); - } + try { + int port = std::stoi(portStr); + endPoint.__set_ip(ip); + endPoint.__set_port(port); + } catch (const std::exception& e) { + endPoint.__set_ip(endPointUrl); + } - return endPoint; + return endPoint; } diff --git a/iotdb-client/client-cpp/src/main/Common.h b/iotdb-client/client-cpp/src/main/Common.h index afdfac130da66..ab2f2562e3f94 100644 --- a/iotdb-client/client-cpp/src/main/Common.h +++ b/iotdb-client/client-cpp/src/main/Common.h @@ -37,14 +37,14 @@ using namespace std; +using ::apache::thrift::TException; using ::apache::thrift::protocol::TBinaryProtocol; using ::apache::thrift::protocol::TCompactProtocol; +using ::apache::thrift::transport::TBufferedTransport; +using ::apache::thrift::transport::TFramedTransport; using ::apache::thrift::transport::TSocket; using ::apache::thrift::transport::TTransport; using ::apache::thrift::transport::TTransportException; -using ::apache::thrift::transport::TBufferedTransport; -using ::apache::thrift::transport::TFramedTransport; -using ::apache::thrift::TException; using namespace std; @@ -62,41 +62,39 @@ std::tm convertToTimestamp(int64_t value, int32_t timeFactor); std::tm int32ToDate(int32_t value); namespace Version { -enum Version { - V_0_12, V_0_13, V_1_0 -}; +enum Version { V_0_12, V_0_13, V_1_0 }; } namespace CompressionType { enum CompressionType { - UNCOMPRESSED = (char)0, - SNAPPY = (char)1, - GZIP = (char)2, - LZO = (char)3, - SDT = (char)4, - PAA = (char)5, - PLA = (char)6, - LZ4 = (char)7, - ZSTD = (char)8, - LZMA2 = (char)9, + UNCOMPRESSED = (char)0, + SNAPPY = (char)1, + GZIP = (char)2, + LZO = (char)3, + SDT = (char)4, + PAA = (char)5, + PLA = (char)6, + LZ4 = (char)7, + ZSTD = (char)8, + LZMA2 = (char)9, }; } namespace TSDataType { enum TSDataType { - BOOLEAN = (char)0, - INT32 = (char)1, - INT64 = (char)2, - FLOAT = (char)3, - DOUBLE = (char)4, - TEXT = (char)5, - VECTOR = (char)6, - UNKNOWN = (char)7, - TIMESTAMP = (char)8, - DATE = (char)9, - BLOB = (char)10, - STRING = (char)11, - OBJECT = (char)12 + BOOLEAN = (char)0, + INT32 = (char)1, + INT64 = (char)2, + FLOAT = (char)3, + DOUBLE = (char)4, + TEXT = (char)5, + VECTOR = (char)6, + UNKNOWN = (char)7, + TIMESTAMP = (char)8, + DATE = (char)9, + BLOB = (char)10, + STRING = (char)11, + OBJECT = (char)12 }; } @@ -104,426 +102,410 @@ TSDataType::TSDataType getDataTypeByStr(const std::string& typeStr); namespace TSEncoding { enum TSEncoding { - PLAIN = (char)0, - DICTIONARY = (char)1, - RLE = (char)2, - DIFF = (char)3, - TS_2DIFF = (char)4, - BITMAP = (char)5, - GORILLA_V1 = (char)6, - REGULAR = (char)7, - GORILLA = (char)8, - ZIGZAG = (char)9, - FREQ = (char)10, - INVALID_ENCODING = (char)255 + PLAIN = (char)0, + DICTIONARY = (char)1, + RLE = (char)2, + DIFF = (char)3, + TS_2DIFF = (char)4, + BITMAP = (char)5, + GORILLA_V1 = (char)6, + REGULAR = (char)7, + GORILLA = (char)8, + ZIGZAG = (char)9, + FREQ = (char)10, + INVALID_ENCODING = (char)255 }; } namespace TSStatusCode { enum TSStatusCode { - SUCCESS_STATUS = 200, - - // System level - INCOMPATIBLE_VERSION = 201, - CONFIGURATION_ERROR = 202, - START_UP_ERROR = 203, - SHUT_DOWN_ERROR = 204, - - // General Error - UNSUPPORTED_OPERATION = 300, - EXECUTE_STATEMENT_ERROR = 301, - MULTIPLE_ERROR = 302, - ILLEGAL_PARAMETER = 303, - OVERLAP_WITH_EXISTING_TASK = 304, - INTERNAL_SERVER_ERROR = 305, - - // Client, - REDIRECTION_RECOMMEND = 400, - - // Schema Engine - DATABASE_NOT_EXIST = 500, - DATABASE_ALREADY_EXISTS = 501, - SERIES_OVERFLOW = 502, - TIMESERIES_ALREADY_EXIST = 503, - TIMESERIES_IN_BLACK_LIST = 504, - ALIAS_ALREADY_EXIST = 505, - PATH_ALREADY_EXIST = 506, - METADATA_ERROR = 507, - PATH_NOT_EXIST = 508, - ILLEGAL_PATH = 509, - CREATE_TEMPLATE_ERROR = 510, - DUPLICATED_TEMPLATE = 511, - UNDEFINED_TEMPLATE = 512, - TEMPLATE_NOT_SET = 513, - DIFFERENT_TEMPLATE = 514, - TEMPLATE_IS_IN_USE = 515, - TEMPLATE_INCOMPATIBLE = 516, - SEGMENT_NOT_FOUND = 517, - PAGE_OUT_OF_SPACE = 518, - RECORD_DUPLICATED = 519, - SEGMENT_OUT_OF_SPACE = 520, - PBTREE_FILE_NOT_EXISTS = 521, - OVERSIZE_RECORD = 522, - PBTREE_FILE_REDO_LOG_BROKEN = 523, - TEMPLATE_NOT_ACTIVATED = 524, - - // Storage Engine - SYSTEM_READ_ONLY = 600, - STORAGE_ENGINE_ERROR = 601, - STORAGE_ENGINE_NOT_READY = 602, - - // Query Engine - PLAN_FAILED_NETWORK_PARTITION = 721 + SUCCESS_STATUS = 200, + + // System level + INCOMPATIBLE_VERSION = 201, + CONFIGURATION_ERROR = 202, + START_UP_ERROR = 203, + SHUT_DOWN_ERROR = 204, + + // General Error + UNSUPPORTED_OPERATION = 300, + EXECUTE_STATEMENT_ERROR = 301, + MULTIPLE_ERROR = 302, + ILLEGAL_PARAMETER = 303, + OVERLAP_WITH_EXISTING_TASK = 304, + INTERNAL_SERVER_ERROR = 305, + + // Client, + REDIRECTION_RECOMMEND = 400, + + // Schema Engine + DATABASE_NOT_EXIST = 500, + DATABASE_ALREADY_EXISTS = 501, + SERIES_OVERFLOW = 502, + TIMESERIES_ALREADY_EXIST = 503, + TIMESERIES_IN_BLACK_LIST = 504, + ALIAS_ALREADY_EXIST = 505, + PATH_ALREADY_EXIST = 506, + METADATA_ERROR = 507, + PATH_NOT_EXIST = 508, + ILLEGAL_PATH = 509, + CREATE_TEMPLATE_ERROR = 510, + DUPLICATED_TEMPLATE = 511, + UNDEFINED_TEMPLATE = 512, + TEMPLATE_NOT_SET = 513, + DIFFERENT_TEMPLATE = 514, + TEMPLATE_IS_IN_USE = 515, + TEMPLATE_INCOMPATIBLE = 516, + SEGMENT_NOT_FOUND = 517, + PAGE_OUT_OF_SPACE = 518, + RECORD_DUPLICATED = 519, + SEGMENT_OUT_OF_SPACE = 520, + PBTREE_FILE_NOT_EXISTS = 521, + OVERSIZE_RECORD = 522, + PBTREE_FILE_REDO_LOG_BROKEN = 523, + TEMPLATE_NOT_ACTIVATED = 524, + + // Storage Engine + SYSTEM_READ_ONLY = 600, + STORAGE_ENGINE_ERROR = 601, + STORAGE_ENGINE_NOT_READY = 602, + + // Query Engine + PLAN_FAILED_NETWORK_PARTITION = 721 }; } class Field { public: - TSDataType::TSDataType dataType = TSDataType::UNKNOWN; - boost::optional boolV; - boost::optional intV; - boost::optional dateV; - boost::optional longV; - boost::optional floatV; - boost::optional doubleV; - boost::optional stringV; - - explicit Field(TSDataType::TSDataType a) { - dataType = a; - } - - Field() = default; - - /** True if this field is SQL NULL (optional for the active dataType is unset). Unknown types are treated as null. */ - bool isNull() const { - switch (dataType) { - case TSDataType::BOOLEAN: - return !boolV.is_initialized(); - case TSDataType::INT32: - return !intV.is_initialized(); - case TSDataType::INT64: - case TSDataType::TIMESTAMP: - return !longV.is_initialized(); - case TSDataType::FLOAT: - return !floatV.is_initialized(); - case TSDataType::DOUBLE: - return !doubleV.is_initialized(); - case TSDataType::TEXT: - case TSDataType::STRING: - case TSDataType::BLOB: - return !stringV.is_initialized(); - case TSDataType::DATE: - return !dateV.is_initialized(); - default: - return true; - } - } + TSDataType::TSDataType dataType = TSDataType::UNKNOWN; + boost::optional boolV; + boost::optional intV; + boost::optional dateV; + boost::optional longV; + boost::optional floatV; + boost::optional doubleV; + boost::optional stringV; + + explicit Field(TSDataType::TSDataType a) { + dataType = a; + } + + Field() = default; + + /** True if this field is SQL NULL (optional for the active dataType is unset). Unknown types are treated as null. */ + bool isNull() const { + switch (dataType) { + case TSDataType::BOOLEAN: + return !boolV.is_initialized(); + case TSDataType::INT32: + return !intV.is_initialized(); + case TSDataType::INT64: + case TSDataType::TIMESTAMP: + return !longV.is_initialized(); + case TSDataType::FLOAT: + return !floatV.is_initialized(); + case TSDataType::DOUBLE: + return !doubleV.is_initialized(); + case TSDataType::TEXT: + case TSDataType::STRING: + case TSDataType::BLOB: + return !stringV.is_initialized(); + case TSDataType::DATE: + return !dateV.is_initialized(); + default: + return true; + } + } }; -enum class ColumnCategory { - TAG, - FIELD, - ATTRIBUTE -}; +enum class ColumnCategory { TAG, FIELD, ATTRIBUTE }; class MyStringBuffer { public: - MyStringBuffer(); - explicit MyStringBuffer(const std::string& str); - - void reserve(size_t n); - void clear(); - bool hasRemaining(); - int getInt(); - boost::gregorian::date getDate(); - int64_t getInt64(); - float getFloat(); - double getDouble(); - char getChar(); - bool getBool(); - std::string getString(); - - void putInt(int ins); - void putDate(boost::gregorian::date date); - void putInt64(int64_t ins); - void putFloat(float ins); - void putDouble(double ins); - void putChar(char ins); - void putBool(bool ins); - void putString(const std::string& ins); - void concat(const std::string& ins); + MyStringBuffer(); + explicit MyStringBuffer(const std::string& str); + + void reserve(size_t n); + void clear(); + bool hasRemaining(); + int getInt(); + boost::gregorian::date getDate(); + int64_t getInt64(); + float getFloat(); + double getDouble(); + char getChar(); + bool getBool(); + std::string getString(); + + void putInt(int ins); + void putDate(boost::gregorian::date date); + void putInt64(int64_t ins); + void putFloat(float ins); + void putDouble(double ins); + void putChar(char ins); + void putBool(bool ins); + void putString(const std::string& ins); + void concat(const std::string& ins); public: - std::string str; - size_t pos; + std::string str; + size_t pos; private: - void checkBigEndian(); - const char* getOrderedByte(size_t len); - void putOrderedByte(char* buf, int len); + void checkBigEndian(); + const char* getOrderedByte(size_t len); + void putOrderedByte(char* buf, int len); private: - bool isBigEndian{}; - char numericBuf[8]{}; //only be used by int, long, float, double etc. + bool isBigEndian{}; + char numericBuf[8]{}; //only be used by int, long, float, double etc. }; class BitMap { public: - explicit BitMap(size_t size = 0); - void resize(size_t size); - bool mark(size_t position); - bool unmark(size_t position); - void markAll(); - void reset(); - bool isMarked(size_t position) const; - bool isAllUnmarked() const; - bool isAllMarked() const; - const std::vector& getByteArray() const; - size_t getSize() const; + explicit BitMap(size_t size = 0); + void resize(size_t size); + bool mark(size_t position); + bool unmark(size_t position); + void markAll(); + void reset(); + bool isMarked(size_t position) const; + bool isAllUnmarked() const; + bool isAllMarked() const; + const std::vector& getByteArray() const; + size_t getSize() const; private: - size_t size; - std::vector bits; + size_t size; + std::vector bits; }; class IoTDBException : public std::exception { public: - IoTDBException() = default; + IoTDBException() = default; - explicit IoTDBException(const std::string& m) : message(m) { - } + explicit IoTDBException(const std::string& m) : message(m) {} - explicit IoTDBException(const char* m) : message(m) { - } + explicit IoTDBException(const char* m) : message(m) {} - virtual const char* what() const noexcept override { - return message.c_str(); - } + virtual const char* what() const noexcept override { + return message.c_str(); + } private: - std::string message; + std::string message; }; class DateTimeParseException : public IoTDBException { private: - std::string parsedString; - int errorIndex; + std::string parsedString; + int errorIndex; public: - explicit DateTimeParseException(const std::string& message, - std::string parsedData, - int errorIndex) - : IoTDBException(message), - parsedString(std::move(parsedData)), - errorIndex(errorIndex) { - } - - explicit DateTimeParseException(const std::string& message, - std::string parsedData, - int errorIndex, - const std::exception& cause) - : IoTDBException(message + " [Caused by: " + cause.what() + "]"), - parsedString(std::move(parsedData)), - errorIndex(errorIndex) { - } - - const std::string& getParsedString() const noexcept { - return parsedString; - } - - int getErrorIndex() const noexcept { - return errorIndex; - } - - const char* what() const noexcept override { - static std::string fullMsg; - fullMsg = std::string(IoTDBException::what()) + - "\nParsed data: " + parsedString + - "\nError index: " + std::to_string(errorIndex); - return fullMsg.c_str(); - } + explicit DateTimeParseException(const std::string& message, std::string parsedData, + int errorIndex) + : IoTDBException(message), parsedString(std::move(parsedData)), errorIndex(errorIndex) {} + + explicit DateTimeParseException(const std::string& message, std::string parsedData, + int errorIndex, const std::exception& cause) + : IoTDBException(message + " [Caused by: " + cause.what() + "]"), + parsedString(std::move(parsedData)), errorIndex(errorIndex) {} + + const std::string& getParsedString() const noexcept { + return parsedString; + } + + int getErrorIndex() const noexcept { + return errorIndex; + } + + const char* what() const noexcept override { + static std::string fullMsg; + fullMsg = std::string(IoTDBException::what()) + "\nParsed data: " + parsedString + + "\nError index: " + std::to_string(errorIndex); + return fullMsg.c_str(); + } }; class IoTDBConnectionException : public IoTDBException { public: - IoTDBConnectionException() { - } + IoTDBConnectionException() {} - explicit IoTDBConnectionException(const char* m) : IoTDBException(m) { - } + explicit IoTDBConnectionException(const char* m) : IoTDBException(m) {} - explicit IoTDBConnectionException(const std::string& m) : IoTDBException(m) { - } + explicit IoTDBConnectionException(const std::string& m) : IoTDBException(m) {} }; class ExecutionException : public IoTDBException { public: - ExecutionException() { - } + ExecutionException() {} - explicit ExecutionException(const char* m) : IoTDBException(m) { - } + explicit ExecutionException(const char* m) : IoTDBException(m) {} - explicit ExecutionException(const std::string& m) : IoTDBException(m) { - } + explicit ExecutionException(const std::string& m) : IoTDBException(m) {} - explicit ExecutionException(const std::string& m, const TSStatus& tsStatus) : IoTDBException(m), status(tsStatus) { - } + explicit ExecutionException(const std::string& m, const TSStatus& tsStatus) + : IoTDBException(m), status(tsStatus) {} - TSStatus status; + TSStatus status; }; class BatchExecutionException : public IoTDBException { public: - BatchExecutionException() { - } + BatchExecutionException() {} - explicit BatchExecutionException(const char* m) : IoTDBException(m) { - } + explicit BatchExecutionException(const char* m) : IoTDBException(m) {} - explicit BatchExecutionException(const std::string& m) : IoTDBException(m) { - } + explicit BatchExecutionException(const std::string& m) : IoTDBException(m) {} - explicit BatchExecutionException(const std::vector& statusList) : statusList(statusList) { - } + explicit BatchExecutionException(const std::vector& statusList) + : statusList(statusList) {} - BatchExecutionException(const std::string& m, const std::vector& statusList) : IoTDBException(m), - statusList(statusList) { - } + BatchExecutionException(const std::string& m, const std::vector& statusList) + : IoTDBException(m), statusList(statusList) {} - std::vector statusList; + std::vector statusList; }; class RedirectException : public IoTDBException { public: - RedirectException() { - } + RedirectException() {} - explicit RedirectException(const char* m) : IoTDBException(m) { - } + explicit RedirectException(const char* m) : IoTDBException(m) {} - explicit RedirectException(const std::string& m) : IoTDBException(m) { - } + explicit RedirectException(const std::string& m) : IoTDBException(m) {} - RedirectException(const std::string& m, const TEndPoint& endPoint) : IoTDBException(m), endPoint(endPoint) { - } + RedirectException(const std::string& m, const TEndPoint& endPoint) + : IoTDBException(m), endPoint(endPoint) {} - RedirectException(const std::string& m, const map& deviceEndPointMap) : IoTDBException(m), - deviceEndPointMap(deviceEndPointMap) { - } + RedirectException(const std::string& m, const map& deviceEndPointMap) + : IoTDBException(m), deviceEndPointMap(deviceEndPointMap) {} - RedirectException(const std::string& m, const vector& endPointList) : IoTDBException(m), - endPointList(endPointList) { - } + RedirectException(const std::string& m, const vector& endPointList) + : IoTDBException(m), endPointList(endPointList) {} - TEndPoint endPoint; - map deviceEndPointMap; - vector endPointList; + TEndPoint endPoint; + map deviceEndPointMap; + vector endPointList; }; class UnSupportedDataTypeException : public IoTDBException { public: - UnSupportedDataTypeException() { - } + UnSupportedDataTypeException() {} - explicit UnSupportedDataTypeException(const char* m) : IoTDBException(m) { - } + explicit UnSupportedDataTypeException(const char* m) : IoTDBException(m) {} - explicit UnSupportedDataTypeException(const std::string& m) : IoTDBException("UnSupported dataType: " + m) { - } + explicit UnSupportedDataTypeException(const std::string& m) + : IoTDBException("UnSupported dataType: " + m) {} }; class SchemaNotFoundException : public IoTDBException { public: - SchemaNotFoundException() { - } + SchemaNotFoundException() {} - explicit SchemaNotFoundException(const char* m) : IoTDBException(m) { - } + explicit SchemaNotFoundException(const char* m) : IoTDBException(m) {} - explicit SchemaNotFoundException(const std::string& m) : IoTDBException(m) { - } + explicit SchemaNotFoundException(const std::string& m) : IoTDBException(m) {} }; class StatementExecutionException : public IoTDBException { public: - StatementExecutionException() { - } + StatementExecutionException() {} - explicit StatementExecutionException(const char* m) : IoTDBException(m) { - } + explicit StatementExecutionException(const char* m) : IoTDBException(m) {} - explicit StatementExecutionException(const std::string& m) : IoTDBException(m) { - } + explicit StatementExecutionException(const std::string& m) : IoTDBException(m) {} }; -enum LogLevelType { - LEVEL_DEBUG = 0, - LEVEL_INFO, - LEVEL_WARN, - LEVEL_ERROR -}; +enum LogLevelType { LEVEL_DEBUG = 0, LEVEL_INFO, LEVEL_WARN, LEVEL_ERROR }; extern LogLevelType LOG_LEVEL; -#define log_debug(fmt,...) do {if(LOG_LEVEL <= LEVEL_DEBUG) {string s=string("[DEBUG] %s:%d (%s) - ") + fmt + "\n"; printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);}} while(0) -#define log_info(fmt,...) do {if(LOG_LEVEL <= LEVEL_INFO) {string s=string("[INFO] %s:%d (%s) - ") + fmt + "\n"; printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);}} while(0) -#define log_warn(fmt,...) do {if(LOG_LEVEL <= LEVEL_WARN) {string s=string("[WARN] %s:%d (%s) - ") + fmt + "\n"; printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);}} while(0) -#define log_error(fmt,...) do {if(LOG_LEVEL <= LEVEL_ERROR) {string s=string("[ERROR] %s:%d (%s) - ") + fmt + "\n"; printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);}} while(0) +#define log_debug(fmt, ...) \ + do { \ + if (LOG_LEVEL <= LEVEL_DEBUG) { \ + string s = string("[DEBUG] %s:%d (%s) - ") + fmt + "\n"; \ + printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \ + } \ + } while (0) +#define log_info(fmt, ...) \ + do { \ + if (LOG_LEVEL <= LEVEL_INFO) { \ + string s = string("[INFO] %s:%d (%s) - ") + fmt + "\n"; \ + printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \ + } \ + } while (0) +#define log_warn(fmt, ...) \ + do { \ + if (LOG_LEVEL <= LEVEL_WARN) { \ + string s = string("[WARN] %s:%d (%s) - ") + fmt + "\n"; \ + printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \ + } \ + } while (0) +#define log_error(fmt, ...) \ + do { \ + if (LOG_LEVEL <= LEVEL_ERROR) { \ + string s = string("[ERROR] %s:%d (%s) - ") + fmt + "\n"; \ + printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \ + } \ + } while (0) class RpcUtils { public: - std::shared_ptr SUCCESS_STATUS; + std::shared_ptr SUCCESS_STATUS; - RpcUtils() { - SUCCESS_STATUS = std::make_shared(); - SUCCESS_STATUS->__set_code(TSStatusCode::SUCCESS_STATUS); - } + RpcUtils() { + SUCCESS_STATUS = std::make_shared(); + SUCCESS_STATUS->__set_code(TSStatusCode::SUCCESS_STATUS); + } - static void verifySuccess(const TSStatus& status); + static void verifySuccess(const TSStatus& status); - static void verifySuccessWithRedirection(const TSStatus& status); + static void verifySuccessWithRedirection(const TSStatus& status); - static void verifySuccessWithRedirectionForMultiDevices(const TSStatus& status, vector devices); + static void verifySuccessWithRedirectionForMultiDevices(const TSStatus& status, + vector devices); - static void verifySuccess(const std::vector& statuses); + static void verifySuccess(const std::vector& statuses); - static TSStatus getStatus(TSStatusCode::TSStatusCode tsStatusCode); + static TSStatus getStatus(TSStatusCode::TSStatusCode tsStatusCode); - static TSStatus getStatus(int code, const std::string& message); + static TSStatus getStatus(int code, const std::string& message); - static std::shared_ptr getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode); + static std::shared_ptr + getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode); - static std::shared_ptr - getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode, const std::string& message); + static std::shared_ptr + getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode, const std::string& message); - static std::shared_ptr getTSExecuteStatementResp(const TSStatus& status); + static std::shared_ptr getTSExecuteStatementResp(const TSStatus& status); - static std::shared_ptr getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode); + static std::shared_ptr + getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode); - static std::shared_ptr - getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode, const std::string& appendMessage); + static std::shared_ptr + getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode, const std::string& appendMessage); - static std::shared_ptr getTSFetchResultsResp(const TSStatus& status); + static std::shared_ptr getTSFetchResultsResp(const TSStatus& status); }; class UrlUtils { private: - static const std::string PORT_SEPARATOR; - static const std::string ABB_COLON; + static const std::string PORT_SEPARATOR; + static const std::string ABB_COLON; - UrlUtils() = delete; - ~UrlUtils() = delete; + UrlUtils() = delete; + ~UrlUtils() = delete; public: - /** + /** * Parse TEndPoint from a given TEndPointUrl * example:[D80:0000:0000:0000:ABAA:0000:00C2:0002]:22227 * * @param endPointUrl ip:port * @return TEndPoint with default values if parse error */ - static TEndPoint parseTEndPointIpv4AndIpv6Url(const std::string& endPointUrl); + static TEndPoint parseTEndPointIpv4AndIpv6Url(const std::string& endPointUrl); }; #endif diff --git a/iotdb-client/client-cpp/src/main/DeviceID.h b/iotdb-client/client-cpp/src/main/DeviceID.h index df2682cd5199e..6903a71b8e88b 100644 --- a/iotdb-client/client-cpp/src/main/DeviceID.h +++ b/iotdb-client/client-cpp/src/main/DeviceID.h @@ -32,130 +32,134 @@ static const std::string PATH_SEPARATOR = "."; class IDeviceID { public: - virtual ~IDeviceID() = default; - virtual std::string get_table_name() { return ""; } - virtual int segment_num() { return 0; } - virtual const std::vector& get_segments() const { - return empty_segments_; - } - virtual std::string get_device_name() const { return ""; }; - virtual bool operator<(const IDeviceID& other) { return 0; } - virtual bool operator==(const IDeviceID& other) { return false; } - virtual bool operator!=(const IDeviceID& other) { return false; } + virtual ~IDeviceID() = default; + virtual std::string get_table_name() { + return ""; + } + virtual int segment_num() { + return 0; + } + virtual const std::vector& get_segments() const { + return empty_segments_; + } + virtual std::string get_device_name() const { + return ""; + }; + virtual bool operator<(const IDeviceID& other) { + return 0; + } + virtual bool operator==(const IDeviceID& other) { + return false; + } + virtual bool operator!=(const IDeviceID& other) { + return false; + } protected: - IDeviceID() : empty_segments_() {} + IDeviceID() : empty_segments_() {} private: - const std::vector empty_segments_; + const std::vector empty_segments_; }; struct IDeviceIDComparator { - bool operator()(const std::shared_ptr& lhs, - const std::shared_ptr& rhs) const { - return *lhs < *rhs; - } + bool operator()(const std::shared_ptr& lhs, + const std::shared_ptr& rhs) const { + return *lhs < *rhs; + } }; class StringArrayDeviceID : public IDeviceID { public: - explicit StringArrayDeviceID(const std::vector& segments) - : segments_(formalize(segments)) {} + explicit StringArrayDeviceID(const std::vector& segments) + : segments_(formalize(segments)) {} - explicit StringArrayDeviceID() : segments_() {} + explicit StringArrayDeviceID() : segments_() {} - ~StringArrayDeviceID() override = default; + ~StringArrayDeviceID() override = default; - std::string get_device_name() const override { - return segments_.empty() ? "" : std::accumulate(std::next(segments_.begin()), segments_.end(), - segments_.front(), - [](std::string a, const std::string& b) { - return std::move(a) + "." + b; - }); - }; + std::string get_device_name() const override { + return segments_.empty() + ? "" + : std::accumulate( + std::next(segments_.begin()), segments_.end(), segments_.front(), + [](std::string a, const std::string& b) { return std::move(a) + "." + b; }); + }; - std::string get_table_name() override { - return segments_.empty() ? "" : segments_[0]; - } + std::string get_table_name() override { + return segments_.empty() ? "" : segments_[0]; + } - int segment_num() override { return static_cast(segments_.size()); } + int segment_num() override { + return static_cast(segments_.size()); + } - const std::vector& get_segments() const override { - return segments_; - } + const std::vector& get_segments() const override { + return segments_; + } - bool operator<(const IDeviceID& other) override { - auto other_segments = other.get_segments(); - return std::lexicographical_compare(segments_.begin(), segments_.end(), - other_segments.begin(), - other_segments.end()); - } + bool operator<(const IDeviceID& other) override { + auto other_segments = other.get_segments(); + return std::lexicographical_compare(segments_.begin(), segments_.end(), other_segments.begin(), + other_segments.end()); + } - bool operator==(const IDeviceID& other) override { - auto other_segments = other.get_segments(); - return (segments_.size() == other_segments.size()) && - std::equal(segments_.begin(), segments_.end(), - other_segments.begin()); - } + bool operator==(const IDeviceID& other) override { + auto other_segments = other.get_segments(); + return (segments_.size() == other_segments.size()) && + std::equal(segments_.begin(), segments_.end(), other_segments.begin()); + } - bool operator!=(const IDeviceID& other) override { - return !(*this == other); - } + bool operator!=(const IDeviceID& other) override { + return !(*this == other); + } private: - std::vector segments_; - - std::vector formalize( - const std::vector& segments) { - auto it = - std::find_if(segments.rbegin(), segments.rend(), - [](const std::string& seg) { return !seg.empty(); }); - return std::vector(segments.begin(), it.base()); + std::vector segments_; + + std::vector formalize(const std::vector& segments) { + auto it = std::find_if(segments.rbegin(), segments.rend(), + [](const std::string& seg) { return !seg.empty(); }); + return std::vector(segments.begin(), it.base()); + } + + std::vector split_device_id_string(const std::vector& splits) { + size_t segment_cnt = splits.size(); + std::vector final_segments; + + if (segment_cnt == 0) { + return final_segments; } - std::vector split_device_id_string( - const std::vector& splits) { - size_t segment_cnt = splits.size(); - std::vector final_segments; - - if (segment_cnt == 0) { - return final_segments; - } - - if (segment_cnt == 1) { - // "root" -> {"root"} - final_segments.push_back(splits[0]); - } else if (segment_cnt < static_cast( - DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME + 1)) { - // "root.a" -> {"root", "a"} - // "root.a.b" -> {"root.a", "b"} - std::string table_name = std::accumulate( - splits.begin(), splits.end() - 1, std::string(), - [](const std::string& a, const std::string& b) { - return a.empty() ? b : a + PATH_SEPARATOR + b; - }); - final_segments.push_back(table_name); - final_segments.push_back(splits.back()); - } else { - // "root.a.b.c" -> {"root.a.b", "c"} - // "root.a.b.c.d" -> {"root.a.b", "c", "d"} - std::string table_name = std::accumulate( - splits.begin(), - splits.begin() + DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME, - std::string(), [](const std::string& a, const std::string& b) { - return a.empty() ? b : a + PATH_SEPARATOR + b; - }); - - final_segments.emplace_back(std::move(table_name)); - final_segments.insert( - final_segments.end(), - splits.begin() + DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME, - splits.end()); - } - - return final_segments; + if (segment_cnt == 1) { + // "root" -> {"root"} + final_segments.push_back(splits[0]); + } else if (segment_cnt < static_cast(DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME + 1)) { + // "root.a" -> {"root", "a"} + // "root.a.b" -> {"root.a", "b"} + std::string table_name = std::accumulate(splits.begin(), splits.end() - 1, std::string(), + [](const std::string& a, const std::string& b) { + return a.empty() ? b : a + PATH_SEPARATOR + b; + }); + final_segments.push_back(table_name); + final_segments.push_back(splits.back()); + } else { + // "root.a.b.c" -> {"root.a.b", "c"} + // "root.a.b.c.d" -> {"root.a.b", "c", "d"} + std::string table_name = + std::accumulate(splits.begin(), splits.begin() + DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME, + std::string(), [](const std::string& a, const std::string& b) { + return a.empty() ? b : a + PATH_SEPARATOR + b; + }); + + final_segments.emplace_back(std::move(table_name)); + final_segments.insert(final_segments.end(), + splits.begin() + DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME, splits.end()); } + + return final_segments; + } }; -} +} // namespace storage #endif \ No newline at end of file diff --git a/iotdb-client/client-cpp/src/main/IoTDBRpcDataSet.cpp b/iotdb-client/client-cpp/src/main/IoTDBRpcDataSet.cpp index 2afef2b99684b..8b02a35607950 100644 --- a/iotdb-client/client-cpp/src/main/IoTDBRpcDataSet.cpp +++ b/iotdb-client/client-cpp/src/main/IoTDBRpcDataSet.cpp @@ -35,240 +35,214 @@ const std::string IoTDBRpcDataSet::MILLISECOND = "ms"; const std::string IoTDBRpcDataSet::MICROSECOND = "us"; const std::string IoTDBRpcDataSet::NANOSECOND = "ns"; -IoTDBRpcDataSet::IoTDBRpcDataSet(const std::string& sql, - const std::vector& columnNameList, - const std::vector& columnTypeList, - const std::map& columnNameIndex, - bool ignoreTimestamp, - bool moreData, - int64_t queryId, - int64_t statementId, - std::shared_ptr client, - int64_t sessionId, - const std::vector& queryResult, - int32_t fetchSize, - const int64_t timeout, - const std::string& zoneId, - const std::string& timeFormat, - int32_t timeFactor, - std::vector& columnIndex2TsBlockColumnIndexList) - : sql_(sql), - isClosed_(false), - client_(client), - fetchSize_(fetchSize), - timeout_(timeout), - hasCachedRecord_(false), - lastReadWasNull_(false), - columnSize_(static_cast(columnNameList.size())), - sessionId_(sessionId), - queryId_(queryId), - statementId_(statementId), - time_(0), - ignoreTimestamp_(ignoreTimestamp), - moreData_(moreData), - queryResult_(queryResult), - curTsBlock_(nullptr), - queryResultSize_(static_cast(queryResult.size())), - queryResultIndex_(0), - tsBlockSize_(0), - tsBlockIndex_(-1), - timeZoneId_(zoneId), - timeFormat_(timeFormat), +IoTDBRpcDataSet::IoTDBRpcDataSet( + const std::string& sql, const std::vector& columnNameList, + const std::vector& columnTypeList, + const std::map& columnNameIndex, bool ignoreTimestamp, bool moreData, + int64_t queryId, int64_t statementId, std::shared_ptr client, + int64_t sessionId, const std::vector& queryResult, int32_t fetchSize, + const int64_t timeout, const std::string& zoneId, const std::string& timeFormat, + int32_t timeFactor, std::vector& columnIndex2TsBlockColumnIndexList) + : sql_(sql), isClosed_(false), client_(client), fetchSize_(fetchSize), timeout_(timeout), + hasCachedRecord_(false), lastReadWasNull_(false), + columnSize_(static_cast(columnNameList.size())), sessionId_(sessionId), + queryId_(queryId), statementId_(statementId), time_(0), ignoreTimestamp_(ignoreTimestamp), + moreData_(moreData), queryResult_(queryResult), curTsBlock_(nullptr), + queryResultSize_(static_cast(queryResult.size())), queryResultIndex_(0), + tsBlockSize_(0), tsBlockIndex_(-1), timeZoneId_(zoneId), timeFormat_(timeFormat), timeFactor_(timeFactor) { - int columnStartIndex = 1; - int resultSetColumnSize = columnNameList_.size(); - // newly generated or updated columnIndex2TsBlockColumnIndexList.size() may not be equal to - // columnNameList.size() - // so we need startIndexForColumnIndex2TsBlockColumnIndexList to adjust the mapping relation - int startIndexForColumnIndex2TsBlockColumnIndexList = 0; - // for Time Column in tree model which should always be the first column and its index for - // TsBlockColumn is -1 + int columnStartIndex = 1; + int resultSetColumnSize = columnNameList_.size(); + // newly generated or updated columnIndex2TsBlockColumnIndexList.size() may not be equal to + // columnNameList.size() + // so we need startIndexForColumnIndex2TsBlockColumnIndexList to adjust the mapping relation + int startIndexForColumnIndex2TsBlockColumnIndexList = 0; + // for Time Column in tree model which should always be the first column and its index for + // TsBlockColumn is -1 + if (!ignoreTimestamp) { + columnNameList_.push_back(TimestampColumnName); + columnTypeList_.push_back("INT64"); + columnName2TsBlockColumnIndexMap_[TimestampColumnName] = -1; + columnOrdinalMap_[TimestampColumnName] = 1; + if (!columnIndex2TsBlockColumnIndexList.empty()) { + columnIndex2TsBlockColumnIndexList.insert(columnIndex2TsBlockColumnIndexList.begin(), -1); + startIndexForColumnIndex2TsBlockColumnIndexList = 1; + } + columnStartIndex++; + resultSetColumnSize++; + } + + if (columnIndex2TsBlockColumnIndexList.empty()) { + columnIndex2TsBlockColumnIndexList.reserve(resultSetColumnSize); if (!ignoreTimestamp) { - columnNameList_.push_back(TimestampColumnName); - columnTypeList_.push_back("INT64"); - columnName2TsBlockColumnIndexMap_[TimestampColumnName] = -1; - columnOrdinalMap_[TimestampColumnName] = 1; - if (!columnIndex2TsBlockColumnIndexList.empty()) { - columnIndex2TsBlockColumnIndexList.insert(columnIndex2TsBlockColumnIndexList.begin(), -1); - startIndexForColumnIndex2TsBlockColumnIndexList = 1; - } - columnStartIndex++; - resultSetColumnSize++; + startIndexForColumnIndex2TsBlockColumnIndexList = 1; + columnIndex2TsBlockColumnIndexList.push_back(-1); } - - if (columnIndex2TsBlockColumnIndexList.empty()) { - columnIndex2TsBlockColumnIndexList.reserve(resultSetColumnSize); - if (!ignoreTimestamp) { - startIndexForColumnIndex2TsBlockColumnIndexList = 1; - columnIndex2TsBlockColumnIndexList.push_back(-1); - } - for (size_t i = 0; i < columnNameList.size(); ++i) { - columnIndex2TsBlockColumnIndexList.push_back(i); - } + for (size_t i = 0; i < columnNameList.size(); ++i) { + columnIndex2TsBlockColumnIndexList.push_back(i); } + } + + columnNameList_.insert(columnNameList_.end(), columnNameList.begin(), columnNameList.end()); + columnTypeList_.insert(columnTypeList_.end(), columnTypeList.begin(), columnTypeList.end()); - columnNameList_.insert(columnNameList_.end(), columnNameList.begin(), columnNameList.end()); - columnTypeList_.insert(columnTypeList_.end(), columnTypeList.begin(), columnTypeList.end()); + // Initialize data types for TsBlock columns + int32_t tsBlockColumnSize = 0; + for (auto value : columnIndex2TsBlockColumnIndexList) { + if (value > tsBlockColumnSize) { + tsBlockColumnSize = value; + } + } + tsBlockColumnSize += 1; + dataTypeForTsBlockColumn_.resize(tsBlockColumnSize); - // Initialize data types for TsBlock columns - int32_t tsBlockColumnSize = 0; - for (auto value : columnIndex2TsBlockColumnIndexList) { - if (value > tsBlockColumnSize) { - tsBlockColumnSize = value; - } + // Populate data types and maps + for (size_t i = 0; i < columnNameList.size(); i++) { + auto columnName = columnNameList[i]; + int32_t tsBlockColumnIndex = + columnIndex2TsBlockColumnIndexList[i + startIndexForColumnIndex2TsBlockColumnIndexList]; + if (tsBlockColumnIndex != -1) { + dataTypeForTsBlockColumn_[tsBlockColumnIndex] = getDataTypeByStr(columnTypeList[i]); } - tsBlockColumnSize += 1; - dataTypeForTsBlockColumn_.resize(tsBlockColumnSize); - - // Populate data types and maps - for (size_t i = 0; i < columnNameList.size(); i++) { - auto columnName = columnNameList[i]; - int32_t tsBlockColumnIndex = columnIndex2TsBlockColumnIndexList[i + - startIndexForColumnIndex2TsBlockColumnIndexList]; - if (tsBlockColumnIndex != -1) { - dataTypeForTsBlockColumn_[tsBlockColumnIndex] = getDataTypeByStr(columnTypeList[i]); - } - - if (columnName2TsBlockColumnIndexMap_.find(columnName) == columnName2TsBlockColumnIndexMap_.end()) { - columnOrdinalMap_[columnName] = i + columnStartIndex; - columnName2TsBlockColumnIndexMap_[columnName] = tsBlockColumnIndex; - } + + if (columnName2TsBlockColumnIndexMap_.find(columnName) == + columnName2TsBlockColumnIndexMap_.end()) { + columnOrdinalMap_[columnName] = i + columnStartIndex; + columnName2TsBlockColumnIndexMap_[columnName] = tsBlockColumnIndex; } + } - timePrecision_ = getTimePrecision(timeFactor_); - columnIndex2TsBlockColumnIndexList_ = columnIndex2TsBlockColumnIndexList; + timePrecision_ = getTimePrecision(timeFactor_); + columnIndex2TsBlockColumnIndexList_ = columnIndex2TsBlockColumnIndexList; } IoTDBRpcDataSet::~IoTDBRpcDataSet() { - if (!isClosed_) { - close(); - } + if (!isClosed_) { + close(); + } } bool IoTDBRpcDataSet::next() { - if (hasCachedBlock()) { - lastReadWasNull_ = false; - constructOneRow(); - return true; - } + if (hasCachedBlock()) { + lastReadWasNull_ = false; + constructOneRow(); + return true; + } - if (hasCachedByteBuffer()) { - constructOneTsBlock(); - constructOneRow(); - return true; - } + if (hasCachedByteBuffer()) { + constructOneTsBlock(); + constructOneRow(); + return true; + } - if (moreData_) { - bool hasResultSet = fetchResults(); - if (hasResultSet && hasCachedByteBuffer()) { - constructOneTsBlock(); - constructOneRow(); - return true; - } + if (moreData_) { + bool hasResultSet = fetchResults(); + if (hasResultSet && hasCachedByteBuffer()) { + constructOneTsBlock(); + constructOneRow(); + return true; } + } - close(); - return false; + close(); + return false; } void IoTDBRpcDataSet::close(bool forceClose) { - if ((!forceClose) && isClosed_) { - return; - } - TSCloseOperationReq closeReq; - closeReq.__set_sessionId(sessionId_); - closeReq.__set_statementId(statementId_); - closeReq.__set_queryId(queryId_); - TSStatus tsStatus; - try { - client_->closeOperation(tsStatus, closeReq); - RpcUtils::verifySuccess(tsStatus); - } - catch (const TTransportException& e) { - log_debug(e.what()); - throw IoTDBConnectionException(e.what()); - } catch (const IoTDBException& e) { - log_debug(e.what()); - throw; - } catch (exception& e) { - log_debug(e.what()); - throw IoTDBException(e.what()); - } - isClosed_ = true; - client_ = nullptr; + if ((!forceClose) && isClosed_) { + return; + } + TSCloseOperationReq closeReq; + closeReq.__set_sessionId(sessionId_); + closeReq.__set_statementId(statementId_); + closeReq.__set_queryId(queryId_); + TSStatus tsStatus; + try { + client_->closeOperation(tsStatus, closeReq); + RpcUtils::verifySuccess(tsStatus); + } catch (const TTransportException& e) { + log_debug(e.what()); + throw IoTDBConnectionException(e.what()); + } catch (const IoTDBException& e) { + log_debug(e.what()); + throw; + } catch (exception& e) { + log_debug(e.what()); + throw IoTDBException(e.what()); + } + isClosed_ = true; + client_ = nullptr; } bool IoTDBRpcDataSet::fetchResults() { - if (isClosed_) { - throw IoTDBException("This data set is already closed"); - } - - TSFetchResultsReq req; - req.__set_sessionId(sessionId_); - req.__set_statement(sql_); - req.__set_fetchSize(fetchSize_); - req.__set_queryId(queryId_); - req.__set_isAlign(true); - req.__set_timeout(timeout_); - TSFetchResultsResp resp; - client_->fetchResultsV2(resp, req); - RpcUtils::verifySuccess(resp.status); - moreData_ = resp.moreData; - if (!resp.hasResultSet) { - close(); - } - else { - queryResult_ = resp.queryResult; - queryResultIndex_ = 0; - if (!queryResult_.empty()) { - queryResultSize_ = queryResult_.size(); - } - else { - queryResultSize_ = 0; - } - tsBlockIndex_ = -1; - tsBlockSize_ = 0; + if (isClosed_) { + throw IoTDBException("This data set is already closed"); + } + + TSFetchResultsReq req; + req.__set_sessionId(sessionId_); + req.__set_statement(sql_); + req.__set_fetchSize(fetchSize_); + req.__set_queryId(queryId_); + req.__set_isAlign(true); + req.__set_timeout(timeout_); + TSFetchResultsResp resp; + client_->fetchResultsV2(resp, req); + RpcUtils::verifySuccess(resp.status); + moreData_ = resp.moreData; + if (!resp.hasResultSet) { + close(); + } else { + queryResult_ = resp.queryResult; + queryResultIndex_ = 0; + if (!queryResult_.empty()) { + queryResultSize_ = queryResult_.size(); + } else { + queryResultSize_ = 0; } - return resp.hasResultSet; + tsBlockIndex_ = -1; + tsBlockSize_ = 0; + } + return resp.hasResultSet; } void IoTDBRpcDataSet::constructOneRow() { - tsBlockIndex_++; - hasCachedRecord_ = true; - time_ = curTsBlock_->getTimeColumn()->getLong(tsBlockIndex_); + tsBlockIndex_++; + hasCachedRecord_ = true; + time_ = curTsBlock_->getTimeColumn()->getLong(tsBlockIndex_); } void IoTDBRpcDataSet::constructOneTsBlock() { - lastReadWasNull_ = false; - const auto& curTsBlockBytes = queryResult_[queryResultIndex_]; - queryResultIndex_++; - curTsBlock_ = TsBlock::deserialize(curTsBlockBytes); - tsBlockIndex_ = -1; - tsBlockSize_ = curTsBlock_->getPositionCount(); + lastReadWasNull_ = false; + const auto& curTsBlockBytes = queryResult_[queryResultIndex_]; + queryResultIndex_++; + curTsBlock_ = TsBlock::deserialize(curTsBlockBytes); + tsBlockIndex_ = -1; + tsBlockSize_ = curTsBlock_->getPositionCount(); } bool IoTDBRpcDataSet::isNullByIndex(int32_t columnIndex) { - int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); - return isNull(index, tsBlockIndex_); + int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); + return isNull(index, tsBlockIndex_); } bool IoTDBRpcDataSet::isNullByColumnName(const std::string& columnName) { - int32_t index = getTsBlockColumnIndexForColumnName(columnName); - return isNull(index, tsBlockIndex_); + int32_t index = getTsBlockColumnIndexForColumnName(columnName); + return isNull(index, tsBlockIndex_); } bool IoTDBRpcDataSet::isNull(int32_t index, int32_t rowNum) { - return index >= 0 && curTsBlock_->getColumn(index)->isNull(rowNum); + return index >= 0 && curTsBlock_->getColumn(index)->isNull(rowNum); } boost::optional IoTDBRpcDataSet::getBooleanByIndex(int32_t columnIndex) { - int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); - return getBooleanByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); + return getBooleanByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getBoolean(const std::string& columnName) { - int32_t index = getTsBlockColumnIndexForColumnName(columnName); - return getBooleanByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnName(columnName); + return getBooleanByTsBlockColumnIndex(index); } // Note: tsBlockColumnIndex < 0 indicates the time pseudo-column in tree model. @@ -276,366 +250,361 @@ boost::optional IoTDBRpcDataSet::getBoolean(const std::string& columnName) // All other typed getters throw IoTDBException to prevent undefined behavior // from accessing valueColumns_ with a negative index. boost::optional IoTDBRpcDataSet::getBooleanByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { - checkRecord(); - if (tsBlockColumnIndex < 0) { - throw IoTDBException("Cannot read boolean from time column"); - } - if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { - lastReadWasNull_ = false; - return curTsBlock_->getColumn(tsBlockColumnIndex)->getBoolean(tsBlockIndex_); - } - else { - lastReadWasNull_ = true; - return boost::none; - } + checkRecord(); + if (tsBlockColumnIndex < 0) { + throw IoTDBException("Cannot read boolean from time column"); + } + if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { + lastReadWasNull_ = false; + return curTsBlock_->getColumn(tsBlockColumnIndex)->getBoolean(tsBlockIndex_); + } else { + lastReadWasNull_ = true; + return boost::none; + } } boost::optional IoTDBRpcDataSet::getDoubleByIndex(int32_t columnIndex) { - int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); - return getDoubleByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); + return getDoubleByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getDouble(const std::string& columnName) { - int32_t index = getTsBlockColumnIndexForColumnName(columnName); - return getDoubleByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnName(columnName); + return getDoubleByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getDoubleByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { - checkRecord(); - if (tsBlockColumnIndex < 0) { - throw IoTDBException("Cannot read double from time column"); - } - if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { - lastReadWasNull_ = false; - return curTsBlock_->getColumn(tsBlockColumnIndex)->getDouble(tsBlockIndex_); - } - else { - lastReadWasNull_ = true; - return boost::none; - } + checkRecord(); + if (tsBlockColumnIndex < 0) { + throw IoTDBException("Cannot read double from time column"); + } + if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { + lastReadWasNull_ = false; + return curTsBlock_->getColumn(tsBlockColumnIndex)->getDouble(tsBlockIndex_); + } else { + lastReadWasNull_ = true; + return boost::none; + } } boost::optional IoTDBRpcDataSet::getFloatByIndex(int32_t columnIndex) { - int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); - return getFloatByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); + return getFloatByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getFloat(const std::string& columnName) { - int32_t index = getTsBlockColumnIndexForColumnName(columnName); - return getFloatByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnName(columnName); + return getFloatByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getFloatByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { - checkRecord(); - if (tsBlockColumnIndex < 0) { - throw IoTDBException("Cannot read float from time column"); - } - if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { - lastReadWasNull_ = false; - return curTsBlock_->getColumn(tsBlockColumnIndex)->getFloat(tsBlockIndex_); - } - else { - lastReadWasNull_ = true; - return boost::none; - } + checkRecord(); + if (tsBlockColumnIndex < 0) { + throw IoTDBException("Cannot read float from time column"); + } + if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { + lastReadWasNull_ = false; + return curTsBlock_->getColumn(tsBlockColumnIndex)->getFloat(tsBlockIndex_); + } else { + lastReadWasNull_ = true; + return boost::none; + } } boost::optional IoTDBRpcDataSet::getIntByIndex(int32_t columnIndex) { - int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); - return getIntByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); + return getIntByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getInt(const std::string& columnName) { - int32_t index = getTsBlockColumnIndexForColumnName(columnName); - return getIntByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnName(columnName); + return getIntByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getIntByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { - checkRecord(); - if (tsBlockColumnIndex < 0) { - throw IoTDBException("Cannot read int32 from time column"); - } - if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { - lastReadWasNull_ = false; - TSDataType::TSDataType dataType = curTsBlock_->getColumn(tsBlockColumnIndex)->getDataType(); - if (dataType == TSDataType::INT64) { - return static_cast(curTsBlock_->getColumn(tsBlockColumnIndex)->getLong(tsBlockIndex_)); - } - return curTsBlock_->getColumn(tsBlockColumnIndex)->getInt(tsBlockIndex_); - } - else { - lastReadWasNull_ = true; - return boost::none; + checkRecord(); + if (tsBlockColumnIndex < 0) { + throw IoTDBException("Cannot read int32 from time column"); + } + if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { + lastReadWasNull_ = false; + TSDataType::TSDataType dataType = curTsBlock_->getColumn(tsBlockColumnIndex)->getDataType(); + if (dataType == TSDataType::INT64) { + return static_cast( + curTsBlock_->getColumn(tsBlockColumnIndex)->getLong(tsBlockIndex_)); } + return curTsBlock_->getColumn(tsBlockColumnIndex)->getInt(tsBlockIndex_); + } else { + lastReadWasNull_ = true; + return boost::none; + } } boost::optional IoTDBRpcDataSet::getLongByIndex(int32_t columnIndex) { - int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); - return getLongByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); + return getLongByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getLong(const std::string& columnName) { - int32_t index = getTsBlockColumnIndexForColumnName(columnName); - return getLongByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnName(columnName); + return getLongByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getLongByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { - checkRecord(); - if (tsBlockColumnIndex < 0) { - lastReadWasNull_ = false; - return curTsBlock_->getTimeByIndex(tsBlockIndex_); - } - if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { - lastReadWasNull_ = false; - TSDataType::TSDataType dataType = curTsBlock_->getColumn(tsBlockColumnIndex)->getDataType(); - if (dataType == TSDataType::INT32) { - return static_cast(curTsBlock_->getColumn(tsBlockColumnIndex)->getInt(tsBlockIndex_)); - } - return curTsBlock_->getColumn(tsBlockColumnIndex)->getLong(tsBlockIndex_); - } - else { - lastReadWasNull_ = true; - return boost::none; + checkRecord(); + if (tsBlockColumnIndex < 0) { + lastReadWasNull_ = false; + return curTsBlock_->getTimeByIndex(tsBlockIndex_); + } + if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { + lastReadWasNull_ = false; + TSDataType::TSDataType dataType = curTsBlock_->getColumn(tsBlockColumnIndex)->getDataType(); + if (dataType == TSDataType::INT32) { + return static_cast( + curTsBlock_->getColumn(tsBlockColumnIndex)->getInt(tsBlockIndex_)); } + return curTsBlock_->getColumn(tsBlockColumnIndex)->getLong(tsBlockIndex_); + } else { + lastReadWasNull_ = true; + return boost::none; + } } std::shared_ptr IoTDBRpcDataSet::getBinaryByIndex(int32_t columnIndex) { - int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); - return getBinaryByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); + return getBinaryByTsBlockColumnIndex(index); } std::shared_ptr IoTDBRpcDataSet::getBinary(const std::string& columnName) { - int32_t index = getTsBlockColumnIndexForColumnName(columnName); - return getBinaryByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnName(columnName); + return getBinaryByTsBlockColumnIndex(index); } std::shared_ptr IoTDBRpcDataSet::getBinaryByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { - checkRecord(); - if (tsBlockColumnIndex < 0) { - throw IoTDBException("Cannot read binary from time column"); - } - if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { - lastReadWasNull_ = false; - return curTsBlock_->getColumn(tsBlockColumnIndex)->getBinary(tsBlockIndex_); - } - else { - lastReadWasNull_ = true; - return nullptr; - } + checkRecord(); + if (tsBlockColumnIndex < 0) { + throw IoTDBException("Cannot read binary from time column"); + } + if (!isNull(tsBlockColumnIndex, tsBlockIndex_)) { + lastReadWasNull_ = false; + return curTsBlock_->getColumn(tsBlockColumnIndex)->getBinary(tsBlockIndex_); + } else { + lastReadWasNull_ = true; + return nullptr; + } } boost::optional IoTDBRpcDataSet::getStringByIndex(int32_t columnIndex) { - int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); - return getStringByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); + return getStringByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getString(const std::string& columnName) { - int32_t index = getTsBlockColumnIndexForColumnName(columnName); - return getStringByTsBlockColumnIndex(index); -} - -boost::optional IoTDBRpcDataSet::getStringByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { - checkRecord(); - if (tsBlockColumnIndex < 0) { - int64_t timestamp = curTsBlock_->getTimeByIndex(tsBlockIndex_); - return std::to_string(timestamp); - } - if (isNull(tsBlockColumnIndex, tsBlockIndex_)) { - lastReadWasNull_ = true; - return boost::none; - } - lastReadWasNull_ = false; - return getStringByTsBlockColumnIndexAndDataType(tsBlockColumnIndex, - getDataTypeByTsBlockColumnIndex(tsBlockColumnIndex)); -} - -std::string IoTDBRpcDataSet::getStringByTsBlockColumnIndexAndDataType(int32_t index, - TSDataType::TSDataType tsDataType) { - switch (tsDataType) { - case TSDataType::BOOLEAN: - return std::to_string(curTsBlock_->getColumn(index)->getBoolean(tsBlockIndex_)); - case TSDataType::INT32: - return std::to_string(curTsBlock_->getColumn(index)->getInt(tsBlockIndex_)); - case TSDataType::INT64: - return std::to_string(curTsBlock_->getColumn(index)->getLong(tsBlockIndex_)); - case TSDataType::TIMESTAMP: { - int64_t value = curTsBlock_->getColumn(index)->getLong(tsBlockIndex_); - return formatDatetime(timeFormat_, timePrecision_, value, timeZoneId_); - } - case TSDataType::FLOAT: - return std::to_string(curTsBlock_->getColumn(index)->getFloat(tsBlockIndex_)); - case TSDataType::DOUBLE: - return std::to_string(curTsBlock_->getColumn(index)->getDouble(tsBlockIndex_)); - case TSDataType::TEXT: - case TSDataType::STRING: - case TSDataType::OBJECT: - case TSDataType::BLOB: { - auto binary = curTsBlock_->getColumn(index)->getBinary(tsBlockIndex_); - return binary->getStringValue(); - } - case TSDataType::DATE: { - int32_t value = curTsBlock_->getColumn(index)->getInt(tsBlockIndex_); - auto date = parseIntToDate(value); - return boost::gregorian::to_iso_extended_string(date); - } - default: - return ""; - } + int32_t index = getTsBlockColumnIndexForColumnName(columnName); + return getStringByTsBlockColumnIndex(index); +} + +boost::optional +IoTDBRpcDataSet::getStringByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { + checkRecord(); + if (tsBlockColumnIndex < 0) { + int64_t timestamp = curTsBlock_->getTimeByIndex(tsBlockIndex_); + return std::to_string(timestamp); + } + if (isNull(tsBlockColumnIndex, tsBlockIndex_)) { + lastReadWasNull_ = true; + return boost::none; + } + lastReadWasNull_ = false; + return getStringByTsBlockColumnIndexAndDataType( + tsBlockColumnIndex, getDataTypeByTsBlockColumnIndex(tsBlockColumnIndex)); +} + +std::string +IoTDBRpcDataSet::getStringByTsBlockColumnIndexAndDataType(int32_t index, + TSDataType::TSDataType tsDataType) { + switch (tsDataType) { + case TSDataType::BOOLEAN: + return std::to_string(curTsBlock_->getColumn(index)->getBoolean(tsBlockIndex_)); + case TSDataType::INT32: + return std::to_string(curTsBlock_->getColumn(index)->getInt(tsBlockIndex_)); + case TSDataType::INT64: + return std::to_string(curTsBlock_->getColumn(index)->getLong(tsBlockIndex_)); + case TSDataType::TIMESTAMP: { + int64_t value = curTsBlock_->getColumn(index)->getLong(tsBlockIndex_); + return formatDatetime(timeFormat_, timePrecision_, value, timeZoneId_); + } + case TSDataType::FLOAT: + return std::to_string(curTsBlock_->getColumn(index)->getFloat(tsBlockIndex_)); + case TSDataType::DOUBLE: + return std::to_string(curTsBlock_->getColumn(index)->getDouble(tsBlockIndex_)); + case TSDataType::TEXT: + case TSDataType::STRING: + case TSDataType::OBJECT: + case TSDataType::BLOB: { + auto binary = curTsBlock_->getColumn(index)->getBinary(tsBlockIndex_); + return binary->getStringValue(); + } + case TSDataType::DATE: { + int32_t value = curTsBlock_->getColumn(index)->getInt(tsBlockIndex_); + auto date = parseIntToDate(value); + return boost::gregorian::to_iso_extended_string(date); + } + default: + return ""; + } } boost::optional IoTDBRpcDataSet::getTimestampByIndex(int32_t columnIndex) { - int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); - return getTimestampByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); + return getTimestampByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getTimestamp(const std::string& columnName) { - int32_t index = getTsBlockColumnIndexForColumnName(columnName); - return getTimestampByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnName(columnName); + return getTimestampByTsBlockColumnIndex(index); } -boost::optional IoTDBRpcDataSet::getTimestampByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { - return getLongByTsBlockColumnIndex(tsBlockColumnIndex); +boost::optional +IoTDBRpcDataSet::getTimestampByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { + return getLongByTsBlockColumnIndex(tsBlockColumnIndex); } boost::optional IoTDBRpcDataSet::getDateByIndex(int32_t columnIndex) { - int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); - return getDateByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); + return getDateByTsBlockColumnIndex(index); } boost::optional IoTDBRpcDataSet::getDate(const std::string& columnName) { - int32_t index = getTsBlockColumnIndexForColumnName(columnName); - return getDateByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnName(columnName); + return getDateByTsBlockColumnIndex(index); } -boost::optional IoTDBRpcDataSet::getDateByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { - auto value = getIntByTsBlockColumnIndex(tsBlockColumnIndex); - if (!value.is_initialized()) { - return boost::none; - } - return parseIntToDate(value.value()); +boost::optional +IoTDBRpcDataSet::getDateByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { + auto value = getIntByTsBlockColumnIndex(tsBlockColumnIndex); + if (!value.is_initialized()) { + return boost::none; + } + return parseIntToDate(value.value()); } TSDataType::TSDataType IoTDBRpcDataSet::getDataTypeByIndex(int32_t columnIndex) { - int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); - return getDataTypeByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnIndex(columnIndex); + return getDataTypeByTsBlockColumnIndex(index); } TSDataType::TSDataType IoTDBRpcDataSet::getDataType(const std::string& columnName) { - int32_t index = getTsBlockColumnIndexForColumnName(columnName); - return getDataTypeByTsBlockColumnIndex(index); + int32_t index = getTsBlockColumnIndexForColumnName(columnName); + return getDataTypeByTsBlockColumnIndex(index); } int32_t IoTDBRpcDataSet::getTsBlockColumnIndexForColumnIndex(int32_t columnIndex) { - const int32_t adjusted_index = columnIndex - 1; - if (adjusted_index >= static_cast(columnIndex2TsBlockColumnIndexList_.size()) || - adjusted_index < 0) { - throw std::out_of_range("Index " + std::to_string(adjusted_index) + - " out of range [0, " + - std::to_string(columnIndex2TsBlockColumnIndexList_.size()) + ")"); - } - return columnIndex2TsBlockColumnIndexList_[adjusted_index]; + const int32_t adjusted_index = columnIndex - 1; + if (adjusted_index >= static_cast(columnIndex2TsBlockColumnIndexList_.size()) || + adjusted_index < 0) { + throw std::out_of_range("Index " + std::to_string(adjusted_index) + " out of range [0, " + + std::to_string(columnIndex2TsBlockColumnIndexList_.size()) + ")"); + } + return columnIndex2TsBlockColumnIndexList_[adjusted_index]; } -TSDataType::TSDataType IoTDBRpcDataSet::getDataTypeByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { - if (tsBlockColumnIndex < 0) { - return TSDataType::TIMESTAMP; - } - else { - return dataTypeForTsBlockColumn_[tsBlockColumnIndex]; - } +TSDataType::TSDataType +IoTDBRpcDataSet::getDataTypeByTsBlockColumnIndex(int32_t tsBlockColumnIndex) { + if (tsBlockColumnIndex < 0) { + return TSDataType::TIMESTAMP; + } else { + return dataTypeForTsBlockColumn_[tsBlockColumnIndex]; + } } int32_t IoTDBRpcDataSet::findColumn(const std::string& columnName) { - auto it = columnOrdinalMap_.find(columnName); - if (it != columnOrdinalMap_.end()) { - return it->second; - } - return -1; + auto it = columnOrdinalMap_.find(columnName); + if (it != columnOrdinalMap_.end()) { + return it->second; + } + return -1; } std::string IoTDBRpcDataSet::findColumnNameByIndex(int32_t columnIndex) { - if (columnIndex <= 0) { - throw IoTDBException("column index should start from 1"); - } - if (columnIndex > static_cast(columnNameList_.size())) { - throw IoTDBException( - "Column index " + std::to_string(columnIndex) + - " is out of range. Valid range is 0 to " + - std::to_string(columnNameList_.size() - 1) - ); - } - return columnNameList_[columnIndex - 1]; + if (columnIndex <= 0) { + throw IoTDBException("column index should start from 1"); + } + if (columnIndex > static_cast(columnNameList_.size())) { + throw IoTDBException("Column index " + std::to_string(columnIndex) + + " is out of range. Valid range is 0 to " + + std::to_string(columnNameList_.size() - 1)); + } + return columnNameList_[columnIndex - 1]; } int32_t IoTDBRpcDataSet::getTsBlockColumnIndexForColumnName(const std::string& columnName) { - auto it = columnName2TsBlockColumnIndexMap_.find(columnName); - if (it == columnName2TsBlockColumnIndexMap_.end()) { - throw IoTDBException("unknown column name: " + columnName); - } - return it->second; + auto it = columnName2TsBlockColumnIndexMap_.find(columnName); + if (it == columnName2TsBlockColumnIndexMap_.end()) { + throw IoTDBException("unknown column name: " + columnName); + } + return it->second; } void IoTDBRpcDataSet::checkRecord() { - if (queryResultIndex_ > queryResultSize_ || - tsBlockIndex_ >= tsBlockSize_ || - queryResult_.empty() || - !curTsBlock_) { - throw IoTDBException("no record remains"); - } + if (queryResultIndex_ > queryResultSize_ || tsBlockIndex_ >= tsBlockSize_ || + queryResult_.empty() || !curTsBlock_) { + throw IoTDBException("no record remains"); + } } int32_t IoTDBRpcDataSet::getValueColumnStartIndex() const { - return ignoreTimestamp_ ? 0 : 1; + return ignoreTimestamp_ ? 0 : 1; } int32_t IoTDBRpcDataSet::getColumnSize() const { - return static_cast(columnNameList_.size()); + return static_cast(columnNameList_.size()); } const std::vector& IoTDBRpcDataSet::getColumnTypeList() const { - return columnTypeList_; + return columnTypeList_; } const std::vector& IoTDBRpcDataSet::getColumnNameList() const { - return columnNameList_; + return columnNameList_; } bool IoTDBRpcDataSet::isClosed() const { - return isClosed_; + return isClosed_; } int32_t IoTDBRpcDataSet::getFetchSize() const { - return fetchSize_; + return fetchSize_; } void IoTDBRpcDataSet::setFetchSize(int32_t fetchSize) { - fetchSize_ = fetchSize; + fetchSize_ = fetchSize; } bool IoTDBRpcDataSet::hasCachedRecord() const { - return hasCachedRecord_; + return hasCachedRecord_; } void IoTDBRpcDataSet::setHasCachedRecord(bool hasCachedRecord) { - hasCachedRecord_ = hasCachedRecord; + hasCachedRecord_ = hasCachedRecord; } bool IoTDBRpcDataSet::isLastReadWasNull() const { - return lastReadWasNull_; + return lastReadWasNull_; } int64_t IoTDBRpcDataSet::getCurrentRowTime() const { - return time_; + return time_; } bool IoTDBRpcDataSet::isIgnoreTimestamp() const { - return ignoreTimestamp_; + return ignoreTimestamp_; } bool IoTDBRpcDataSet::hasCachedBlock() const { - return curTsBlock_ && tsBlockIndex_ < tsBlockSize_ - 1; + return curTsBlock_ && tsBlockIndex_ < tsBlockSize_ - 1; } bool IoTDBRpcDataSet::hasCachedByteBuffer() const { - return !queryResult_.empty() && queryResultIndex_ < queryResultSize_; + return !queryResult_.empty() && queryResultIndex_ < queryResultSize_; } diff --git a/iotdb-client/client-cpp/src/main/IoTDBRpcDataSet.h b/iotdb-client/client-cpp/src/main/IoTDBRpcDataSet.h index 7ec8af5049f32..0e6855f4049ab 100644 --- a/iotdb-client/client-cpp/src/main/IoTDBRpcDataSet.h +++ b/iotdb-client/client-cpp/src/main/IoTDBRpcDataSet.h @@ -31,129 +31,121 @@ class IoTDBRpcDataSet { public: - static const int32_t startIndex; - static const std::string TimestampColumnName; + static const int32_t startIndex; + static const std::string TimestampColumnName; - static const std::string DEFAULT_TIME_FORMAT; - static const std::string TIME_PRECISION; - static const std::string MILLISECOND; - static const std::string MICROSECOND; - static const std::string NANOSECOND; + static const std::string DEFAULT_TIME_FORMAT; + static const std::string TIME_PRECISION; + static const std::string MILLISECOND; + static const std::string MICROSECOND; + static const std::string NANOSECOND; - IoTDBRpcDataSet(const std::string& sql, - const std::vector& columnNameList, - const std::vector& columnTypeList, - const std::map& columnNameIndex, - bool ignoreTimestamp, - bool moreData, - int64_t queryId, - int64_t statementId, - std::shared_ptr client, - int64_t sessionId, - const std::vector& queryResult, - int32_t fetchSize, - int64_t timeout, - const std::string& zoneId, - const std::string& timeFormat, - int32_t timeFactor, - std::vector& columnIndex2TsBlockColumnIndexList); + IoTDBRpcDataSet(const std::string& sql, const std::vector& columnNameList, + const std::vector& columnTypeList, + const std::map& columnNameIndex, bool ignoreTimestamp, + bool moreData, int64_t queryId, int64_t statementId, + std::shared_ptr client, int64_t sessionId, + const std::vector& queryResult, int32_t fetchSize, int64_t timeout, + const std::string& zoneId, const std::string& timeFormat, int32_t timeFactor, + std::vector& columnIndex2TsBlockColumnIndexList); - ~IoTDBRpcDataSet(); + ~IoTDBRpcDataSet(); - bool next(); - void close(bool forceClose = false); + bool next(); + void close(bool forceClose = false); - bool hasCachedBlock() const; - bool hasCachedByteBuffer() const; + bool hasCachedBlock() const; + bool hasCachedByteBuffer() const; - bool isNull(int32_t index, int32_t rowNum); - bool isNullByIndex(int32_t columnIndex); - bool isNullByColumnName(const std::string& columnName); - boost::optional getBooleanByIndex(int32_t columnIndex); - boost::optional getBoolean(const std::string& columnName); - boost::optional getDoubleByIndex(int32_t columnIndex); - boost::optional getDouble(const std::string& columnName); - boost::optional getFloatByIndex(int32_t columnIndex); - boost::optional getFloat(const std::string& columnName); - boost::optional getIntByIndex(int32_t columnIndex); - boost::optional getInt(const std::string& columnName); - boost::optional getLongByIndex(int32_t columnIndex); - boost::optional getLong(const std::string& columnName); - std::shared_ptr getBinaryByIndex(int32_t columnIndex); - std::shared_ptr getBinary(const std::string& columnName); - boost::optional getStringByIndex(int32_t columnIndex); - boost::optional getString(const std::string& columnName); - boost::optional getTimestampByIndex(int32_t columnIndex); - boost::optional getTimestamp(const std::string& columnName); - boost::optional getDateByIndex(int32_t columnIndex); - boost::optional getDate(const std::string& columnName); + bool isNull(int32_t index, int32_t rowNum); + bool isNullByIndex(int32_t columnIndex); + bool isNullByColumnName(const std::string& columnName); + boost::optional getBooleanByIndex(int32_t columnIndex); + boost::optional getBoolean(const std::string& columnName); + boost::optional getDoubleByIndex(int32_t columnIndex); + boost::optional getDouble(const std::string& columnName); + boost::optional getFloatByIndex(int32_t columnIndex); + boost::optional getFloat(const std::string& columnName); + boost::optional getIntByIndex(int32_t columnIndex); + boost::optional getInt(const std::string& columnName); + boost::optional getLongByIndex(int32_t columnIndex); + boost::optional getLong(const std::string& columnName); + std::shared_ptr getBinaryByIndex(int32_t columnIndex); + std::shared_ptr getBinary(const std::string& columnName); + boost::optional getStringByIndex(int32_t columnIndex); + boost::optional getString(const std::string& columnName); + boost::optional getTimestampByIndex(int32_t columnIndex); + boost::optional getTimestamp(const std::string& columnName); + boost::optional getDateByIndex(int32_t columnIndex); + boost::optional getDate(const std::string& columnName); - TSDataType::TSDataType getDataTypeByIndex(int32_t columnIndex); - TSDataType::TSDataType getDataType(const std::string& columnName); - int32_t findColumn(const std::string& columnName); - std::string findColumnNameByIndex(int32_t columnIndex); - int32_t getValueColumnStartIndex() const; - int32_t getColumnSize() const; - const std::vector& getColumnTypeList() const; - const std::vector& getColumnNameList() const; - bool isClosed() const; - int32_t getFetchSize() const; - void setFetchSize(int32_t fetchSize); - bool hasCachedRecord() const; - void setHasCachedRecord(bool hasCachedRecord); - bool isLastReadWasNull() const; - int64_t getCurrentRowTime() const; - bool isIgnoreTimestamp() const; + TSDataType::TSDataType getDataTypeByIndex(int32_t columnIndex); + TSDataType::TSDataType getDataType(const std::string& columnName); + int32_t findColumn(const std::string& columnName); + std::string findColumnNameByIndex(int32_t columnIndex); + int32_t getValueColumnStartIndex() const; + int32_t getColumnSize() const; + const std::vector& getColumnTypeList() const; + const std::vector& getColumnNameList() const; + bool isClosed() const; + int32_t getFetchSize() const; + void setFetchSize(int32_t fetchSize); + bool hasCachedRecord() const; + void setHasCachedRecord(bool hasCachedRecord); + bool isLastReadWasNull() const; + int64_t getCurrentRowTime() const; + bool isIgnoreTimestamp() const; private: - bool fetchResults(); - void constructOneRow(); - void constructOneTsBlock(); - int32_t getTsBlockColumnIndexForColumnName(const std::string& columnName); - int32_t getTsBlockColumnIndexForColumnIndex(int32_t columnIndex); - void checkRecord(); - TSDataType::TSDataType getDataTypeByTsBlockColumnIndex(int32_t tsBlockColumnIndex); - boost::optional getBooleanByTsBlockColumnIndex(int32_t tsBlockColumnIndex); - std::string getStringByTsBlockColumnIndexAndDataType(int32_t index, TSDataType::TSDataType tsDataType); - boost::optional getDoubleByTsBlockColumnIndex(int32_t tsBlockColumnIndex); - boost::optional getFloatByTsBlockColumnIndex(int32_t tsBlockColumnIndex); - boost::optional getIntByTsBlockColumnIndex(int32_t tsBlockColumnIndex); - boost::optional getLongByTsBlockColumnIndex(int32_t tsBlockColumnIndex); - std::shared_ptr getBinaryByTsBlockColumnIndex(int32_t tsBlockColumnIndex); - boost::optional getStringByTsBlockColumnIndex(int32_t tsBlockColumnIndex); - boost::optional getDateByTsBlockColumnIndex(int32_t tsBlockColumnIndex); - boost::optional getTimestampByTsBlockColumnIndex(int32_t tsBlockColumnIndex); + bool fetchResults(); + void constructOneRow(); + void constructOneTsBlock(); + int32_t getTsBlockColumnIndexForColumnName(const std::string& columnName); + int32_t getTsBlockColumnIndexForColumnIndex(int32_t columnIndex); + void checkRecord(); + TSDataType::TSDataType getDataTypeByTsBlockColumnIndex(int32_t tsBlockColumnIndex); + boost::optional getBooleanByTsBlockColumnIndex(int32_t tsBlockColumnIndex); + std::string getStringByTsBlockColumnIndexAndDataType(int32_t index, + TSDataType::TSDataType tsDataType); + boost::optional getDoubleByTsBlockColumnIndex(int32_t tsBlockColumnIndex); + boost::optional getFloatByTsBlockColumnIndex(int32_t tsBlockColumnIndex); + boost::optional getIntByTsBlockColumnIndex(int32_t tsBlockColumnIndex); + boost::optional getLongByTsBlockColumnIndex(int32_t tsBlockColumnIndex); + std::shared_ptr getBinaryByTsBlockColumnIndex(int32_t tsBlockColumnIndex); + boost::optional getStringByTsBlockColumnIndex(int32_t tsBlockColumnIndex); + boost::optional getDateByTsBlockColumnIndex(int32_t tsBlockColumnIndex); + boost::optional getTimestampByTsBlockColumnIndex(int32_t tsBlockColumnIndex); - std::string sql_; - bool isClosed_; - std::shared_ptr client_; - std::vector columnNameList_; - std::vector columnTypeList_; - std::map columnOrdinalMap_; - std::map columnName2TsBlockColumnIndexMap_; - std::vector columnIndex2TsBlockColumnIndexList_; - std::vector dataTypeForTsBlockColumn_; - int32_t fetchSize_; - int64_t timeout_; - bool hasCachedRecord_; - bool lastReadWasNull_; - int32_t columnSize_; - int64_t sessionId_; - int64_t queryId_; - int64_t statementId_; - int64_t time_; - bool ignoreTimestamp_; - bool moreData_; - std::vector queryResult_; - std::shared_ptr curTsBlock_; - int32_t queryResultSize_; - int32_t queryResultIndex_; - int32_t tsBlockSize_; - int32_t tsBlockIndex_; - std::string timeZoneId_; - std::string timeFormat_; - int32_t timeFactor_; - std::string timePrecision_; + std::string sql_; + bool isClosed_; + std::shared_ptr client_; + std::vector columnNameList_; + std::vector columnTypeList_; + std::map columnOrdinalMap_; + std::map columnName2TsBlockColumnIndexMap_; + std::vector columnIndex2TsBlockColumnIndexList_; + std::vector dataTypeForTsBlockColumn_; + int32_t fetchSize_; + int64_t timeout_; + bool hasCachedRecord_; + bool lastReadWasNull_; + int32_t columnSize_; + int64_t sessionId_; + int64_t queryId_; + int64_t statementId_; + int64_t time_; + bool ignoreTimestamp_; + bool moreData_; + std::vector queryResult_; + std::shared_ptr curTsBlock_; + int32_t queryResultSize_; + int32_t queryResultIndex_; + int32_t tsBlockSize_; + int32_t tsBlockIndex_; + std::string timeZoneId_; + std::string timeFormat_; + int32_t timeFactor_; + std::string timePrecision_; }; #endif // IOTDB_RPC_DATA_SET_H diff --git a/iotdb-client/client-cpp/src/main/NodesSupplier.cpp b/iotdb-client/client-cpp/src/main/NodesSupplier.cpp index ae414e19577ee..3f3a807dae8db 100644 --- a/iotdb-client/client-cpp/src/main/NodesSupplier.cpp +++ b/iotdb-client/client-cpp/src/main/NodesSupplier.cpp @@ -37,144 +37,118 @@ const int NodesSupplier::THRIFT_MAX_FRAME_SIZE = 1048576; const int NodesSupplier::CONNECTION_TIMEOUT_IN_MS = 1000; TEndPoint RoundRobinPolicy::select(const std::vector& nodes) { - static std::atomic_uint index{0}; + static std::atomic_uint index{0}; - if (nodes.empty()) { - throw IoTDBException("No available nodes"); - } + if (nodes.empty()) { + throw IoTDBException("No available nodes"); + } - return nodes[index++ % nodes.size()]; + return nodes[index++ % nodes.size()]; } StaticNodesSupplier::StaticNodesSupplier(const std::vector& nodes, - NodeSelectionPolicy policy) + NodeSelectionPolicy policy) : availableNodes_(nodes), policy_(std::move(policy)) {} boost::optional StaticNodesSupplier::getQueryEndPoint() { - try { - if (availableNodes_.empty()) { - return boost::none; - } - return policy_(availableNodes_); - } catch (const IoTDBException& e) { - return boost::none; + try { + if (availableNodes_.empty()) { + return boost::none; } + return policy_(availableNodes_); + } catch (const IoTDBException& e) { + return boost::none; + } } std::vector StaticNodesSupplier::getEndPointList() { - return availableNodes_; + return availableNodes_; } StaticNodesSupplier::~StaticNodesSupplier() = default; std::shared_ptr NodesSupplier::create( - const std::vector& endpoints, - const std::string& userName, - const std::string& password, - bool useSSL, - const std::string& trustCertFilePath, - const std::string& zoneId, - int32_t thriftDefaultBufferSize, - int32_t thriftMaxFrameSize, - int32_t connectionTimeoutInMs, - bool enableRPCCompression, - const std::string& version, - std::chrono::milliseconds refreshInterval, - NodeSelectionPolicy policy) { - if (endpoints.empty()) { - return nullptr; - } - auto supplier = std::make_shared( - userName, password, useSSL, trustCertFilePath, zoneId, - thriftDefaultBufferSize, thriftMaxFrameSize, connectionTimeoutInMs, - enableRPCCompression, - version, endpoints, policy - ); - supplier->startBackgroundRefresh(refreshInterval); - return supplier; + const std::vector& endpoints, const std::string& userName, + const std::string& password, bool useSSL, const std::string& trustCertFilePath, + const std::string& zoneId, int32_t thriftDefaultBufferSize, int32_t thriftMaxFrameSize, + int32_t connectionTimeoutInMs, bool enableRPCCompression, const std::string& version, + std::chrono::milliseconds refreshInterval, NodeSelectionPolicy policy) { + if (endpoints.empty()) { + return nullptr; + } + auto supplier = std::make_shared( + userName, password, useSSL, trustCertFilePath, zoneId, thriftDefaultBufferSize, + thriftMaxFrameSize, connectionTimeoutInMs, enableRPCCompression, version, endpoints, policy); + supplier->startBackgroundRefresh(refreshInterval); + return supplier; } -NodesSupplier::NodesSupplier( - const std::string& userName, - const std::string& password, - bool useSSL, - const std::string& trustCertFilePath, - const std::string& zoneId, - int32_t thriftDefaultBufferSize, - int32_t thriftMaxFrameSize, - int32_t connectionTimeoutInMs, - bool enableRPCCompression, - const std::string& version, - const std::vector& endpoints, - NodeSelectionPolicy policy) - : userName_(userName) - , password_(password) - , zoneId_(zoneId) - , thriftDefaultBufferSize_(thriftDefaultBufferSize) - , thriftMaxFrameSize_(thriftMaxFrameSize) - , connectionTimeoutInMs_(connectionTimeoutInMs) - , useSSL_(useSSL) - , trustCertFilePath_(trustCertFilePath) - , enableRPCCompression_(enableRPCCompression) - , version_(version) - , endpoints_(endpoints) - , selectionPolicy_(policy) { - deduplicateEndpoints(); +NodesSupplier::NodesSupplier(const std::string& userName, const std::string& password, bool useSSL, + const std::string& trustCertFilePath, const std::string& zoneId, + int32_t thriftDefaultBufferSize, int32_t thriftMaxFrameSize, + int32_t connectionTimeoutInMs, bool enableRPCCompression, + const std::string& version, const std::vector& endpoints, + NodeSelectionPolicy policy) + : userName_(userName), password_(password), zoneId_(zoneId), + thriftDefaultBufferSize_(thriftDefaultBufferSize), thriftMaxFrameSize_(thriftMaxFrameSize), + connectionTimeoutInMs_(connectionTimeoutInMs), useSSL_(useSSL), + trustCertFilePath_(trustCertFilePath), enableRPCCompression_(enableRPCCompression), + version_(version), endpoints_(endpoints), selectionPolicy_(policy) { + deduplicateEndpoints(); } std::vector NodesSupplier::getEndPointList() { - std::lock_guard lock(mutex_); - return endpoints_; + std::lock_guard lock(mutex_); + return endpoints_; } TEndPoint NodesSupplier::selectQueryEndpoint() { - std::lock_guard lock(mutex_); - try { - return selectionPolicy_(endpoints_); - } catch (const std::exception& e) { - log_error("NodesSupplier::selectQueryEndpoint exception: %s", e.what()); - throw IoTDBException("NodesSupplier::selectQueryEndpoint exception, " + std::string(e.what())); - } + std::lock_guard lock(mutex_); + try { + return selectionPolicy_(endpoints_); + } catch (const std::exception& e) { + log_error("NodesSupplier::selectQueryEndpoint exception: %s", e.what()); + throw IoTDBException("NodesSupplier::selectQueryEndpoint exception, " + std::string(e.what())); + } } boost::optional NodesSupplier::getQueryEndPoint() { - try { - return selectQueryEndpoint(); - } catch (const IoTDBException& e) { - return boost::none; - } + try { + return selectQueryEndpoint(); + } catch (const IoTDBException& e) { + return boost::none; + } } NodesSupplier::~NodesSupplier() { - stopBackgroundRefresh(); - if (client_ != nullptr) { - client_->close(); - } + stopBackgroundRefresh(); + if (client_ != nullptr) { + client_->close(); + } } void NodesSupplier::deduplicateEndpoints() { - std::vector uniqueEndpoints; - uniqueEndpoints.reserve(endpoints_.size()); - for (const auto& endpoint : endpoints_) { - if (std::find(uniqueEndpoints.begin(), uniqueEndpoints.end(), endpoint) == uniqueEndpoints.end()) { - uniqueEndpoints.push_back(endpoint); - } + std::vector uniqueEndpoints; + uniqueEndpoints.reserve(endpoints_.size()); + for (const auto& endpoint : endpoints_) { + if (std::find(uniqueEndpoints.begin(), uniqueEndpoints.end(), endpoint) == + uniqueEndpoints.end()) { + uniqueEndpoints.push_back(endpoint); } - endpoints_ = std::move(uniqueEndpoints); + } + endpoints_ = std::move(uniqueEndpoints); } void NodesSupplier::startBackgroundRefresh(std::chrono::milliseconds interval) { - isRunning_ = true; - refreshEndpointList(); - refreshThread_ = std::thread([this, interval] { - while (isRunning_) { - refreshEndpointList(); - std::unique_lock cvLock(this->mutex_); - refreshCondition_.wait_for(cvLock, interval, [this]() { - return !isRunning_.load(); - }); - } - }); + isRunning_ = true; + refreshEndpointList(); + refreshThread_ = std::thread([this, interval] { + while (isRunning_) { + refreshEndpointList(); + std::unique_lock cvLock(this->mutex_); + refreshCondition_.wait_for(cvLock, interval, [this]() { return !isRunning_.load(); }); + } + }); } std::vector NodesSupplier::fetchLatestEndpoints() { @@ -182,7 +156,8 @@ std::vector NodesSupplier::fetchLatestEndpoints() { try { if (client_ == nullptr) { client_ = std::make_shared(endpoint); - client_->init(userName_, password_, enableRPCCompression_, useSSL_, trustCertFilePath_, zoneId_, version_); + client_->init(userName_, password_, enableRPCCompression_, useSSL_, trustCertFilePath_, + zoneId_, version_); } auto sessionDataSet = client_->executeQueryStatement(SHOW_AVAILABLE_URLS_COMMAND); @@ -223,37 +198,37 @@ std::vector NodesSupplier::fetchLatestEndpoints() { newEndpoint.port = port; ret.emplace_back(newEndpoint); } - return ret; // success + return ret; // success } catch (const std::exception& e) { log_warn("Failed to fetch endpoints from " + endpoint.ip + ":" + std::to_string(endpoint.port) + " , error=" + e.what()); - client_.reset(); // reset client before retrying next endpoint - continue; // try next endpoint + client_.reset(); // reset client before retrying next endpoint + continue; // try next endpoint } } throw IoTDBException("NodesSupplier::fetchLatestEndpoints failed: all nodes unreachable."); } void NodesSupplier::refreshEndpointList() { - try { - auto newEndpoints = fetchLatestEndpoints(); - if (newEndpoints.empty()) { - return; - } - - std::lock_guard lock(mutex_); - endpoints_.swap(newEndpoints); - deduplicateEndpoints(); - } catch (const IoTDBException& e) { - log_error(std::string("NodesSupplier::refreshEndpointList failed: ") + e.what()); + try { + auto newEndpoints = fetchLatestEndpoints(); + if (newEndpoints.empty()) { + return; } + + std::lock_guard lock(mutex_); + endpoints_.swap(newEndpoints); + deduplicateEndpoints(); + } catch (const IoTDBException& e) { + log_error(std::string("NodesSupplier::refreshEndpointList failed: ") + e.what()); + } } void NodesSupplier::stopBackgroundRefresh() noexcept { - if (isRunning_.exchange(false)) { - refreshCondition_.notify_all(); - if (refreshThread_.joinable()) { - refreshThread_.join(); - } + if (isRunning_.exchange(false)) { + refreshCondition_.notify_all(); + if (refreshThread_.joinable()) { + refreshThread_.join(); } + } } \ No newline at end of file diff --git a/iotdb-client/client-cpp/src/main/NodesSupplier.h b/iotdb-client/client-cpp/src/main/NodesSupplier.h index f4718f0f02bd3..7c56f8e75ba86 100644 --- a/iotdb-client/client-cpp/src/main/NodesSupplier.h +++ b/iotdb-client/client-cpp/src/main/NodesSupplier.h @@ -35,118 +35,105 @@ class TEndPoint; class RoundRobinPolicy { public: - static TEndPoint select(const std::vector& nodes); + static TEndPoint select(const std::vector& nodes); }; class INodesSupplier { public: - virtual ~INodesSupplier() = default; - virtual boost::optional getQueryEndPoint() = 0; - virtual std::vector getEndPointList() = 0; - using NodeSelectionPolicy = std::function&)>; + virtual ~INodesSupplier() = default; + virtual boost::optional getQueryEndPoint() = 0; + virtual std::vector getEndPointList() = 0; + using NodeSelectionPolicy = std::function&)>; }; class StaticNodesSupplier : public INodesSupplier { public: - explicit StaticNodesSupplier(const std::vector& nodes, - NodeSelectionPolicy policy = RoundRobinPolicy::select); + explicit StaticNodesSupplier(const std::vector& nodes, + NodeSelectionPolicy policy = RoundRobinPolicy::select); - boost::optional getQueryEndPoint() override; + boost::optional getQueryEndPoint() override; - std::vector getEndPointList() override; + std::vector getEndPointList() override; - ~StaticNodesSupplier() override; + ~StaticNodesSupplier() override; private: - const std::vector availableNodes_; - NodeSelectionPolicy policy_; + const std::vector availableNodes_; + NodeSelectionPolicy policy_; }; class NodesSupplier : public INodesSupplier { public: - static const std::string SHOW_AVAILABLE_URLS_COMMAND; - static const std::string RUNNING_STATUS; - static const std::string STATUS_COLUMN_NAME; - static const std::string IP_COLUMN_NAME; - static const std::string PORT_COLUMN_NAME; - static const std::string REMOVING_STATUS; - - static const int64_t TIMEOUT_IN_MS; - static const int FETCH_SIZE; - static const int THRIFT_DEFAULT_BUFFER_SIZE; - static const int THRIFT_MAX_FRAME_SIZE; - static const int CONNECTION_TIMEOUT_IN_MS; - - static std::shared_ptr create( - const std::vector& endpoints, - const std::string& userName, - const std::string& password, - bool useSSL = false, - const std::string& trustCertFilePath = "", - const std::string& zoneId = "", - int32_t thriftDefaultBufferSize = ThriftConnection::THRIFT_DEFAULT_BUFFER_SIZE, - int32_t thriftMaxFrameSize = ThriftConnection::THRIFT_MAX_FRAME_SIZE, - int32_t connectionTimeoutInMs = ThriftConnection::CONNECTION_TIMEOUT_IN_MS, - bool enableRPCCompression = false, - const std::string& version = "V_1_0", - std::chrono::milliseconds refreshInterval = std::chrono::milliseconds(TIMEOUT_IN_MS), - NodeSelectionPolicy policy = RoundRobinPolicy::select - ); - - NodesSupplier( - const std::string& userName, - const std::string& password, - bool useSSL, - const std::string& trustCertFilePath, - const std::string& zoneId, - int32_t thriftDefaultBufferSize, - int32_t thriftMaxFrameSize, - int32_t connectionTimeoutInMs, - bool enableRPCCompression, - const std::string& version, - const std::vector& endpoints, - NodeSelectionPolicy policy - ); - - std::vector getEndPointList() override; - - boost::optional getQueryEndPoint() override; - - ~NodesSupplier() override; + static const std::string SHOW_AVAILABLE_URLS_COMMAND; + static const std::string RUNNING_STATUS; + static const std::string STATUS_COLUMN_NAME; + static const std::string IP_COLUMN_NAME; + static const std::string PORT_COLUMN_NAME; + static const std::string REMOVING_STATUS; + + static const int64_t TIMEOUT_IN_MS; + static const int FETCH_SIZE; + static const int THRIFT_DEFAULT_BUFFER_SIZE; + static const int THRIFT_MAX_FRAME_SIZE; + static const int CONNECTION_TIMEOUT_IN_MS; + + static std::shared_ptr + create(const std::vector& endpoints, const std::string& userName, + const std::string& password, bool useSSL = false, + const std::string& trustCertFilePath = "", const std::string& zoneId = "", + int32_t thriftDefaultBufferSize = ThriftConnection::THRIFT_DEFAULT_BUFFER_SIZE, + int32_t thriftMaxFrameSize = ThriftConnection::THRIFT_MAX_FRAME_SIZE, + int32_t connectionTimeoutInMs = ThriftConnection::CONNECTION_TIMEOUT_IN_MS, + bool enableRPCCompression = false, const std::string& version = "V_1_0", + std::chrono::milliseconds refreshInterval = std::chrono::milliseconds(TIMEOUT_IN_MS), + NodeSelectionPolicy policy = RoundRobinPolicy::select); + + NodesSupplier(const std::string& userName, const std::string& password, bool useSSL, + const std::string& trustCertFilePath, const std::string& zoneId, + int32_t thriftDefaultBufferSize, int32_t thriftMaxFrameSize, + int32_t connectionTimeoutInMs, bool enableRPCCompression, + const std::string& version, const std::vector& endpoints, + NodeSelectionPolicy policy); + + std::vector getEndPointList() override; + + boost::optional getQueryEndPoint() override; + + ~NodesSupplier() override; private: - std::string userName_; - std::string password_; - int32_t thriftDefaultBufferSize_; - int32_t thriftMaxFrameSize_; - int32_t connectionTimeoutInMs_; - bool useSSL_; - std::string trustCertFilePath_; - bool enableRPCCompression_; - std::string version_; - std::string zoneId_; + std::string userName_; + std::string password_; + int32_t thriftDefaultBufferSize_; + int32_t thriftMaxFrameSize_; + int32_t connectionTimeoutInMs_; + bool useSSL_; + std::string trustCertFilePath_; + bool enableRPCCompression_; + std::string version_; + std::string zoneId_; - std::mutex mutex_; - std::vector endpoints_; - NodeSelectionPolicy selectionPolicy_; + std::mutex mutex_; + std::vector endpoints_; + NodeSelectionPolicy selectionPolicy_; - std::atomic isRunning_{false}; - std::thread refreshThread_; - std::condition_variable refreshCondition_; + std::atomic isRunning_{false}; + std::thread refreshThread_; + std::condition_variable refreshCondition_; - std::shared_ptr client_; + std::shared_ptr client_; - void deduplicateEndpoints(); + void deduplicateEndpoints(); - void startBackgroundRefresh(std::chrono::milliseconds interval); + void startBackgroundRefresh(std::chrono::milliseconds interval); - std::vector fetchLatestEndpoints(); + std::vector fetchLatestEndpoints(); - void refreshEndpointList(); + void refreshEndpointList(); - TEndPoint selectQueryEndpoint(); + TEndPoint selectQueryEndpoint(); - void stopBackgroundRefresh() noexcept; + void stopBackgroundRefresh() noexcept; }; #endif \ No newline at end of file diff --git a/iotdb-client/client-cpp/src/main/Session.cpp b/iotdb-client/client-cpp/src/main/Session.cpp index 41744286bb0a8..d1e70e747de58 100644 --- a/iotdb-client/client-cpp/src/main/Session.cpp +++ b/iotdb-client/client-cpp/src/main/Session.cpp @@ -38,468 +38,462 @@ static const int64_t QUERY_TIMEOUT_MS = -1; LogLevelType LOG_LEVEL = LEVEL_DEBUG; TSDataType::TSDataType getTSDataTypeFromString(const string& str) { - // BOOLEAN, INT32, INT64, FLOAT, DOUBLE, TEXT, STRING, BLOB, TIMESTAMP, DATE, NULLTYPE - if (str == "BOOLEAN") { - return TSDataType::BOOLEAN; - } else if (str == "INT32") { - return TSDataType::INT32; - } else if (str == "INT64") { - return TSDataType::INT64; - } else if (str == "FLOAT") { - return TSDataType::FLOAT; - } else if (str == "DOUBLE") { - return TSDataType::DOUBLE; - } else if (str == "TEXT") { - return TSDataType::TEXT; - } else if (str == "TIMESTAMP") { - return TSDataType::TIMESTAMP; - } else if (str == "DATE") { - return TSDataType::DATE; - } else if (str == "BLOB") { - return TSDataType::BLOB; - } else if (str == "STRING") { - return TSDataType::STRING; - } else if (str == "OBJECT") { - return TSDataType::OBJECT; - } - return TSDataType::UNKNOWN; + // BOOLEAN, INT32, INT64, FLOAT, DOUBLE, TEXT, STRING, BLOB, TIMESTAMP, DATE, NULLTYPE + if (str == "BOOLEAN") { + return TSDataType::BOOLEAN; + } else if (str == "INT32") { + return TSDataType::INT32; + } else if (str == "INT64") { + return TSDataType::INT64; + } else if (str == "FLOAT") { + return TSDataType::FLOAT; + } else if (str == "DOUBLE") { + return TSDataType::DOUBLE; + } else if (str == "TEXT") { + return TSDataType::TEXT; + } else if (str == "TIMESTAMP") { + return TSDataType::TIMESTAMP; + } else if (str == "DATE") { + return TSDataType::DATE; + } else if (str == "BLOB") { + return TSDataType::BLOB; + } else if (str == "STRING") { + return TSDataType::STRING; + } else if (str == "OBJECT") { + return TSDataType::OBJECT; + } + return TSDataType::UNKNOWN; } void Tablet::createColumns() { - for (size_t i = 0; i < schemas.size(); i++) { - TSDataType::TSDataType dataType = schemas[i].second; - switch (dataType) { - case TSDataType::BOOLEAN: - values[i] = new bool[maxRowNumber]; - break; - case TSDataType::DATE: - values[i] = new boost::gregorian::date[maxRowNumber]; - break; - case TSDataType::INT32: - values[i] = new int[maxRowNumber]; - break; - case TSDataType::TIMESTAMP: - case TSDataType::INT64: - values[i] = new int64_t[maxRowNumber]; - break; - case TSDataType::FLOAT: - values[i] = new float[maxRowNumber]; - break; - case TSDataType::DOUBLE: - values[i] = new double[maxRowNumber]; - break; - case TSDataType::STRING: - case TSDataType::BLOB: - case TSDataType::OBJECT: - case TSDataType::TEXT: - values[i] = new string[maxRowNumber]; - break; - default: - throw UnSupportedDataTypeException(string("Data type ") + to_string(dataType) + " is not supported."); - } - } -} - -void Tablet::deleteColumns() { - for (size_t i = 0; i < schemas.size(); i++) { - if (!values[i]) continue; - TSDataType::TSDataType dataType = schemas[i].second; - switch (dataType) { - case TSDataType::BOOLEAN: { - bool* valueBuf = (bool*)(values[i]); - delete[] valueBuf; - break; - } - case TSDataType::INT32: { - int* valueBuf = (int*)(values[i]); - delete[] valueBuf; - break; - } - case TSDataType::DATE: { - boost::gregorian::date* valueBuf = (boost::gregorian::date*)(values[i]); - delete[] valueBuf; - break; - } - case TSDataType::TIMESTAMP: - case TSDataType::INT64: { - int64_t* valueBuf = (int64_t*)(values[i]); - delete[] valueBuf; - break; - } - case TSDataType::FLOAT: { - float* valueBuf = (float*)(values[i]); - delete[] valueBuf; - break; - } - case TSDataType::DOUBLE: { - double* valueBuf = (double*)(values[i]); - delete[] valueBuf; - break; - } - case TSDataType::STRING: - case TSDataType::BLOB: - case TSDataType::OBJECT: - case TSDataType::TEXT: { - string* valueBuf = (string*)(values[i]); - delete[] valueBuf; - break; - } - default: - throw UnSupportedDataTypeException(string("Data type ") + to_string(dataType) + " is not supported."); - } - values[i] = nullptr; - } -} - -void Tablet::deepCopyTabletColValue(void* const* srcPtr, void** destPtr, TSDataType::TSDataType type, int maxRowNumber) { - void *src = *srcPtr; - switch (type) { + for (size_t i = 0; i < schemas.size(); i++) { + TSDataType::TSDataType dataType = schemas[i].second; + switch (dataType) { case TSDataType::BOOLEAN: - *destPtr = new bool[maxRowNumber]; - memcpy(*destPtr, src, maxRowNumber * sizeof(bool)); - break; + values[i] = new bool[maxRowNumber]; + break; + case TSDataType::DATE: + values[i] = new boost::gregorian::date[maxRowNumber]; + break; case TSDataType::INT32: - *destPtr = new int32_t[maxRowNumber]; - memcpy(*destPtr, src, maxRowNumber * sizeof(int32_t)); - break; - case TSDataType::INT64: + values[i] = new int[maxRowNumber]; + break; case TSDataType::TIMESTAMP: - *destPtr = new int64_t[maxRowNumber]; - memcpy(*destPtr, src, maxRowNumber * sizeof(int64_t)); - break; + case TSDataType::INT64: + values[i] = new int64_t[maxRowNumber]; + break; case TSDataType::FLOAT: - *destPtr = new float[maxRowNumber]; - memcpy(*destPtr, src, maxRowNumber * sizeof(float)); - break; + values[i] = new float[maxRowNumber]; + break; case TSDataType::DOUBLE: - *destPtr = new double[maxRowNumber]; - memcpy(*destPtr, src, maxRowNumber * sizeof(double)); - break; + values[i] = new double[maxRowNumber]; + break; + case TSDataType::STRING: + case TSDataType::BLOB: + case TSDataType::OBJECT: + case TSDataType::TEXT: + values[i] = new string[maxRowNumber]; + break; + default: + throw UnSupportedDataTypeException(string("Data type ") + to_string(dataType) + + " is not supported."); + } + } +} + +void Tablet::deleteColumns() { + for (size_t i = 0; i < schemas.size(); i++) { + if (!values[i]) + continue; + TSDataType::TSDataType dataType = schemas[i].second; + switch (dataType) { + case TSDataType::BOOLEAN: { + bool* valueBuf = (bool*)(values[i]); + delete[] valueBuf; + break; + } + case TSDataType::INT32: { + int* valueBuf = (int*)(values[i]); + delete[] valueBuf; + break; + } case TSDataType::DATE: { - *destPtr = new boost::gregorian::date[maxRowNumber]; - boost::gregorian::date* srcDate = static_cast(src); - boost::gregorian::date* destDate = static_cast(*destPtr); - for (size_t j = 0; j < maxRowNumber; ++j) { - destDate[j] = srcDate[j]; - } - break; + boost::gregorian::date* valueBuf = (boost::gregorian::date*)(values[i]); + delete[] valueBuf; + break; + } + case TSDataType::TIMESTAMP: + case TSDataType::INT64: { + int64_t* valueBuf = (int64_t*)(values[i]); + delete[] valueBuf; + break; + } + case TSDataType::FLOAT: { + float* valueBuf = (float*)(values[i]); + delete[] valueBuf; + break; + } + case TSDataType::DOUBLE: { + double* valueBuf = (double*)(values[i]); + delete[] valueBuf; + break; } case TSDataType::STRING: - case TSDataType::TEXT: + case TSDataType::BLOB: case TSDataType::OBJECT: - case TSDataType::BLOB: { - *destPtr = new std::string[maxRowNumber]; - std::string* srcStr = static_cast(src); - std::string* destStr = static_cast(*destPtr); - for (size_t j = 0; j < maxRowNumber; ++j) { - destStr[j] = srcStr[j]; - } - break; + case TSDataType::TEXT: { + string* valueBuf = (string*)(values[i]); + delete[] valueBuf; + break; } default: - break; - } + throw UnSupportedDataTypeException(string("Data type ") + to_string(dataType) + + " is not supported."); + } + values[i] = nullptr; + } +} + +void Tablet::deepCopyTabletColValue(void* const* srcPtr, void** destPtr, + TSDataType::TSDataType type, int maxRowNumber) { + void* src = *srcPtr; + switch (type) { + case TSDataType::BOOLEAN: + *destPtr = new bool[maxRowNumber]; + memcpy(*destPtr, src, maxRowNumber * sizeof(bool)); + break; + case TSDataType::INT32: + *destPtr = new int32_t[maxRowNumber]; + memcpy(*destPtr, src, maxRowNumber * sizeof(int32_t)); + break; + case TSDataType::INT64: + case TSDataType::TIMESTAMP: + *destPtr = new int64_t[maxRowNumber]; + memcpy(*destPtr, src, maxRowNumber * sizeof(int64_t)); + break; + case TSDataType::FLOAT: + *destPtr = new float[maxRowNumber]; + memcpy(*destPtr, src, maxRowNumber * sizeof(float)); + break; + case TSDataType::DOUBLE: + *destPtr = new double[maxRowNumber]; + memcpy(*destPtr, src, maxRowNumber * sizeof(double)); + break; + case TSDataType::DATE: { + *destPtr = new boost::gregorian::date[maxRowNumber]; + boost::gregorian::date* srcDate = static_cast(src); + boost::gregorian::date* destDate = static_cast(*destPtr); + for (size_t j = 0; j < maxRowNumber; ++j) { + destDate[j] = srcDate[j]; + } + break; + } + case TSDataType::STRING: + case TSDataType::TEXT: + case TSDataType::OBJECT: + case TSDataType::BLOB: { + *destPtr = new std::string[maxRowNumber]; + std::string* srcStr = static_cast(src); + std::string* destStr = static_cast(*destPtr); + for (size_t j = 0; j < maxRowNumber; ++j) { + destStr[j] = srcStr[j]; + } + break; + } + default: + break; + } } void Tablet::reset() { - rowSize = 0; - for (size_t i = 0; i < schemas.size(); i++) { - bitMaps[i].reset(); - } + rowSize = 0; + for (size_t i = 0; i < schemas.size(); i++) { + bitMaps[i].reset(); + } } size_t Tablet::getTimeBytesSize() { - return rowSize * 8; + return rowSize * 8; } size_t Tablet::getValueByteSize() { - size_t valueOccupation = 0; - for (size_t i = 0; i < schemas.size(); i++) { - switch (schemas[i].second) { - case TSDataType::BOOLEAN: - valueOccupation += rowSize; - break; - case TSDataType::INT32: - valueOccupation += rowSize * 4; - break; - case TSDataType::DATE: - valueOccupation += rowSize * 4; - break; - case TSDataType::TIMESTAMP: - case TSDataType::INT64: - valueOccupation += rowSize * 8; - break; - case TSDataType::FLOAT: - valueOccupation += rowSize * 4; - break; - case TSDataType::DOUBLE: - valueOccupation += rowSize * 8; - break; - case TSDataType::STRING: - case TSDataType::BLOB: - case TSDataType::OBJECT: - case TSDataType::TEXT: { - valueOccupation += rowSize * 4; - string* valueBuf = (string*)(values[i]); - for (size_t j = 0; j < rowSize; j++) { - valueOccupation += valueBuf[j].size(); - } - break; - } - default: - throw UnSupportedDataTypeException( - string("Data type ") + to_string(schemas[i].second) + " is not supported."); - } + size_t valueOccupation = 0; + for (size_t i = 0; i < schemas.size(); i++) { + switch (schemas[i].second) { + case TSDataType::BOOLEAN: + valueOccupation += rowSize; + break; + case TSDataType::INT32: + valueOccupation += rowSize * 4; + break; + case TSDataType::DATE: + valueOccupation += rowSize * 4; + break; + case TSDataType::TIMESTAMP: + case TSDataType::INT64: + valueOccupation += rowSize * 8; + break; + case TSDataType::FLOAT: + valueOccupation += rowSize * 4; + break; + case TSDataType::DOUBLE: + valueOccupation += rowSize * 8; + break; + case TSDataType::STRING: + case TSDataType::BLOB: + case TSDataType::OBJECT: + case TSDataType::TEXT: { + valueOccupation += rowSize * 4; + string* valueBuf = (string*)(values[i]); + for (size_t j = 0; j < rowSize; j++) { + valueOccupation += valueBuf[j].size(); + } + break; } - return valueOccupation; + default: + throw UnSupportedDataTypeException(string("Data type ") + to_string(schemas[i].second) + + " is not supported."); + } + } + return valueOccupation; } void Tablet::setAligned(bool isAligned) { - this->isAligned = isAligned; + this->isAligned = isAligned; } std::shared_ptr Tablet::getDeviceID(int row) { - std::vector id_array(idColumnIndexes.size() + 1); - size_t idArrayIdx = 0; - id_array[idArrayIdx++] = this->deviceId; - for (auto idColumnIndex : idColumnIndexes) { - void* strPtr = getValue(idColumnIndex, row, TSDataType::TEXT); - id_array[idArrayIdx++] = *static_cast(strPtr); - } - return std::make_shared(id_array); + std::vector id_array(idColumnIndexes.size() + 1); + size_t idArrayIdx = 0; + id_array[idArrayIdx++] = this->deviceId; + for (auto idColumnIndex : idColumnIndexes) { + void* strPtr = getValue(idColumnIndex, row, TSDataType::TEXT); + id_array[idArrayIdx++] = *static_cast(strPtr); + } + return std::make_shared(id_array); } string SessionUtils::getTime(const Tablet& tablet) { - MyStringBuffer timeBuffer; - unsigned int n = 8u * tablet.rowSize; - if (n > timeBuffer.str.capacity()) { - timeBuffer.reserve(n); - } + MyStringBuffer timeBuffer; + unsigned int n = 8u * tablet.rowSize; + if (n > timeBuffer.str.capacity()) { + timeBuffer.reserve(n); + } - for (size_t i = 0; i < tablet.rowSize; i++) { - timeBuffer.putInt64(tablet.timestamps[i]); - } - return timeBuffer.str; + for (size_t i = 0; i < tablet.rowSize; i++) { + timeBuffer.putInt64(tablet.timestamps[i]); + } + return timeBuffer.str; } string SessionUtils::getValue(const Tablet& tablet) { - MyStringBuffer valueBuffer; - unsigned int n = 8u * tablet.schemas.size() * tablet.rowSize; - if (n > valueBuffer.str.capacity()) { - valueBuffer.reserve(n); - } - for (size_t i = 0; i < tablet.schemas.size(); i++) { - TSDataType::TSDataType dataType = tablet.schemas[i].second; - const BitMap& bitMap = tablet.bitMaps[i]; - switch (dataType) { - case TSDataType::BOOLEAN: { - bool* valueBuf = (bool*)(tablet.values[i]); - for (size_t index = 0; index < tablet.rowSize; index++) { - if (!bitMap.isMarked(index)) { - valueBuffer.putBool(valueBuf[index]); - } - else { - valueBuffer.putBool(false); - } - } - break; - } - case TSDataType::INT32: { - int* valueBuf = (int*)(tablet.values[i]); - for (size_t index = 0; index < tablet.rowSize; index++) { - if (!bitMap.isMarked(index)) { - valueBuffer.putInt(valueBuf[index]); - } - else { - valueBuffer.putInt((numeric_limits::min)()); - } - } - break; - } - case TSDataType::DATE: { - boost::gregorian::date* valueBuf = (boost::gregorian::date*)(tablet.values[i]); - for (size_t index = 0; index < tablet.rowSize; index++) { - if (!bitMap.isMarked(index)) { - valueBuffer.putDate(valueBuf[index]); - } - else { - valueBuffer.putInt(EMPTY_DATE_INT); - } - } - break; - } - case TSDataType::TIMESTAMP: - case TSDataType::INT64: { - int64_t* valueBuf = (int64_t*)(tablet.values[i]); - for (size_t index = 0; index < tablet.rowSize; index++) { - if (!bitMap.isMarked(index)) { - valueBuffer.putInt64(valueBuf[index]); - } - else { - valueBuffer.putInt64((numeric_limits::min)()); - } - } - break; - } - case TSDataType::FLOAT: { - float* valueBuf = (float*)(tablet.values[i]); - for (size_t index = 0; index < tablet.rowSize; index++) { - if (!bitMap.isMarked(index)) { - valueBuffer.putFloat(valueBuf[index]); - } - else { - valueBuffer.putFloat((numeric_limits::min)()); - } - } - break; - } - case TSDataType::DOUBLE: { - double* valueBuf = (double*)(tablet.values[i]); - for (size_t index = 0; index < tablet.rowSize; index++) { - if (!bitMap.isMarked(index)) { - valueBuffer.putDouble(valueBuf[index]); - } - else { - valueBuffer.putDouble((numeric_limits::min)()); - } - } - break; - } - case TSDataType::STRING: - case TSDataType::BLOB: - case TSDataType::OBJECT: - case TSDataType::TEXT: { - string* valueBuf = (string*)(tablet.values[i]); - for (size_t index = 0; index < tablet.rowSize; index++) { - if (!bitMap.isMarked(index)) { - valueBuffer.putString(valueBuf[index]); - } - else { - valueBuffer.putString(""); - } - } - break; - } - default: - throw UnSupportedDataTypeException(string("Data type ") + to_string(dataType) + " is not supported."); + MyStringBuffer valueBuffer; + unsigned int n = 8u * tablet.schemas.size() * tablet.rowSize; + if (n > valueBuffer.str.capacity()) { + valueBuffer.reserve(n); + } + for (size_t i = 0; i < tablet.schemas.size(); i++) { + TSDataType::TSDataType dataType = tablet.schemas[i].second; + const BitMap& bitMap = tablet.bitMaps[i]; + switch (dataType) { + case TSDataType::BOOLEAN: { + bool* valueBuf = (bool*)(tablet.values[i]); + for (size_t index = 0; index < tablet.rowSize; index++) { + if (!bitMap.isMarked(index)) { + valueBuffer.putBool(valueBuf[index]); + } else { + valueBuffer.putBool(false); + } + } + break; + } + case TSDataType::INT32: { + int* valueBuf = (int*)(tablet.values[i]); + for (size_t index = 0; index < tablet.rowSize; index++) { + if (!bitMap.isMarked(index)) { + valueBuffer.putInt(valueBuf[index]); + } else { + valueBuffer.putInt((numeric_limits::min)()); + } + } + break; + } + case TSDataType::DATE: { + boost::gregorian::date* valueBuf = (boost::gregorian::date*)(tablet.values[i]); + for (size_t index = 0; index < tablet.rowSize; index++) { + if (!bitMap.isMarked(index)) { + valueBuffer.putDate(valueBuf[index]); + } else { + valueBuffer.putInt(EMPTY_DATE_INT); } + } + break; } - for (size_t i = 0; i < tablet.schemas.size(); i++) { - const BitMap& bitMap = tablet.bitMaps[i]; - bool columnHasNull = !bitMap.isAllUnmarked(); - valueBuffer.putChar(columnHasNull ? (char)1 : (char)0); - if (columnHasNull) { - const vector& bytes = bitMap.getByteArray(); - for (size_t index = 0; index < tablet.rowSize / 8 + 1; index++) { - valueBuffer.putChar(bytes[index]); - } + case TSDataType::TIMESTAMP: + case TSDataType::INT64: { + int64_t* valueBuf = (int64_t*)(tablet.values[i]); + for (size_t index = 0; index < tablet.rowSize; index++) { + if (!bitMap.isMarked(index)) { + valueBuffer.putInt64(valueBuf[index]); + } else { + valueBuffer.putInt64((numeric_limits::min)()); + } + } + break; + } + case TSDataType::FLOAT: { + float* valueBuf = (float*)(tablet.values[i]); + for (size_t index = 0; index < tablet.rowSize; index++) { + if (!bitMap.isMarked(index)) { + valueBuffer.putFloat(valueBuf[index]); + } else { + valueBuffer.putFloat((numeric_limits::min)()); + } + } + break; + } + case TSDataType::DOUBLE: { + double* valueBuf = (double*)(tablet.values[i]); + for (size_t index = 0; index < tablet.rowSize; index++) { + if (!bitMap.isMarked(index)) { + valueBuffer.putDouble(valueBuf[index]); + } else { + valueBuffer.putDouble((numeric_limits::min)()); + } + } + break; + } + case TSDataType::STRING: + case TSDataType::BLOB: + case TSDataType::OBJECT: + case TSDataType::TEXT: { + string* valueBuf = (string*)(tablet.values[i]); + for (size_t index = 0; index < tablet.rowSize; index++) { + if (!bitMap.isMarked(index)) { + valueBuffer.putString(valueBuf[index]); + } else { + valueBuffer.putString(""); } + } + break; } - return valueBuffer.str; + default: + throw UnSupportedDataTypeException(string("Data type ") + to_string(dataType) + + " is not supported."); + } + } + for (size_t i = 0; i < tablet.schemas.size(); i++) { + const BitMap& bitMap = tablet.bitMaps[i]; + bool columnHasNull = !bitMap.isAllUnmarked(); + valueBuffer.putChar(columnHasNull ? (char)1 : (char)0); + if (columnHasNull) { + const vector& bytes = bitMap.getByteArray(); + for (size_t index = 0; index < tablet.rowSize / 8 + 1; index++) { + valueBuffer.putChar(bytes[index]); + } + } + } + return valueBuffer.str; } bool SessionUtils::isTabletContainsSingleDevice(Tablet tablet) { - if (tablet.rowSize == 1) { - return true; - } - auto firstDeviceId = tablet.getDeviceID(0); - for (int i = 1; i < tablet.rowSize; ++i) { - if (*firstDeviceId != *tablet.getDeviceID(i)) { - return false; - } - } + if (tablet.rowSize == 1) { return true; + } + auto firstDeviceId = tablet.getDeviceID(0); + for (int i = 1; i < tablet.rowSize; ++i) { + if (*firstDeviceId != *tablet.getDeviceID(i)) { + return false; + } + } + return true; } string MeasurementNode::serialize() const { - MyStringBuffer buffer; - buffer.putString(getName()); - buffer.putChar(getDataType()); - buffer.putChar(getEncoding()); - buffer.putChar(getCompressionType()); - return buffer.str; + MyStringBuffer buffer; + buffer.putString(getName()); + buffer.putChar(getDataType()); + buffer.putChar(getEncoding()); + buffer.putChar(getCompressionType()); + return buffer.str; } string Template::serialize() const { - MyStringBuffer buffer; - stack>> stack; - unordered_set alignedPrefix; - buffer.putString(getName()); - buffer.putBool(isAligned()); - if (isAligned()) { - alignedPrefix.emplace(""); - } - - for (const auto& child : children_) { - stack.push(make_pair("", child.second)); - } - - while (!stack.empty()) { - auto cur = stack.top(); - stack.pop(); - - string prefix = cur.first; - shared_ptr cur_node_ptr = cur.second; - string fullPath(prefix); - - if (!cur_node_ptr->isMeasurement()) { - if (!prefix.empty()) { - fullPath.append("."); - } - fullPath.append(cur_node_ptr->getName()); - if (cur_node_ptr->isAligned()) { - alignedPrefix.emplace(fullPath); - } - for (const auto& child : cur_node_ptr->getChildren()) { - stack.push(make_pair(fullPath, child.second)); - } - } - else { - buffer.putString(prefix); - buffer.putBool(alignedPrefix.find(prefix) != alignedPrefix.end()); - buffer.concat(cur_node_ptr->serialize()); - } - } - - return buffer.str; + MyStringBuffer buffer; + stack>> stack; + unordered_set alignedPrefix; + buffer.putString(getName()); + buffer.putBool(isAligned()); + if (isAligned()) { + alignedPrefix.emplace(""); + } + + for (const auto& child : children_) { + stack.push(make_pair("", child.second)); + } + + while (!stack.empty()) { + auto cur = stack.top(); + stack.pop(); + + string prefix = cur.first; + shared_ptr cur_node_ptr = cur.second; + string fullPath(prefix); + + if (!cur_node_ptr->isMeasurement()) { + if (!prefix.empty()) { + fullPath.append("."); + } + fullPath.append(cur_node_ptr->getName()); + if (cur_node_ptr->isAligned()) { + alignedPrefix.emplace(fullPath); + } + for (const auto& child : cur_node_ptr->getChildren()) { + stack.push(make_pair(fullPath, child.second)); + } + } else { + buffer.putString(prefix); + buffer.putBool(alignedPrefix.find(prefix) != alignedPrefix.end()); + buffer.concat(cur_node_ptr->serialize()); + } + } + + return buffer.str; } /** * When delete variable, make sure release all resource. */ Session::~Session() { - try { - close(); - } - catch (const exception& e) { - log_debug(e.what()); - } + try { + close(); + } catch (const exception& e) { + log_debug(e.what()); + } } void Session::removeBrokenSessionConnection(shared_ptr sessionConnection) { - if (enableRedirection_) { - this->endPointToSessionConnection.erase(sessionConnection->getEndPoint()); - } + if (enableRedirection_) { + this->endPointToSessionConnection.erase(sessionConnection->getEndPoint()); + } - auto it1 = deviceIdToEndpoint.begin(); - while (it1 != deviceIdToEndpoint.end()) { - if (it1->second == sessionConnection->getEndPoint()) { - it1 = deviceIdToEndpoint.erase(it1); - } - else { - ++it1; - } + auto it1 = deviceIdToEndpoint.begin(); + while (it1 != deviceIdToEndpoint.end()) { + if (it1->second == sessionConnection->getEndPoint()) { + it1 = deviceIdToEndpoint.erase(it1); + } else { + ++it1; } + } - auto it2 = tableModelDeviceIdToEndpoint.begin(); - while (it2 != tableModelDeviceIdToEndpoint.end()) { - if (it2->second == sessionConnection->getEndPoint()) { - it2 = tableModelDeviceIdToEndpoint.erase(it2); - } - else { - ++it2; - } + auto it2 = tableModelDeviceIdToEndpoint.begin(); + while (it2 != tableModelDeviceIdToEndpoint.end()) { + if (it2->second == sessionConnection->getEndPoint()) { + it2 = tableModelDeviceIdToEndpoint.erase(it2); + } else { + ++it2; } + } } /** @@ -508,1339 +502,1270 @@ void Session::removeBrokenSessionConnection(shared_ptr sessio * @return whether the batch has been sorted */ bool Session::checkSorted(const Tablet& tablet) { - for (size_t i = 1; i < tablet.rowSize; i++) { - if (tablet.timestamps[i] < tablet.timestamps[i - 1]) { - return false; - } + for (size_t i = 1; i < tablet.rowSize; i++) { + if (tablet.timestamps[i] < tablet.timestamps[i - 1]) { + return false; } - return true; + } + return true; } bool Session::checkSorted(const vector& times) { - for (size_t i = 1; i < times.size(); i++) { - if (times[i] < times[i - 1]) { - return false; - } + for (size_t i = 1; i < times.size(); i++) { + if (times[i] < times[i - 1]) { + return false; } - return true; + } + return true; } template std::vector sortList(const std::vector& valueList, const int* index, int indexLength) { - std::vector sortedValues(valueList.size()); - for (int i = 0; i < indexLength; i++) { - sortedValues[i] = valueList[index[i]]; - } - return sortedValues; + std::vector sortedValues(valueList.size()); + for (int i = 0; i < indexLength; i++) { + sortedValues[i] = valueList[index[i]]; + } + return sortedValues; } -template -void sortValuesList(T* valueList, const int* index, size_t indexLength) { - T* sortedValues = new T[indexLength]; - for (int i = 0; i < indexLength; i++) { - sortedValues[i] = valueList[index[i]]; - } - for (int i = 0; i < indexLength; i++) { - valueList[i] = sortedValues[i]; - } - delete[] sortedValues; +template void sortValuesList(T* valueList, const int* index, size_t indexLength) { + T* sortedValues = new T[indexLength]; + for (int i = 0; i < indexLength; i++) { + sortedValues[i] = valueList[index[i]]; + } + for (int i = 0; i < indexLength; i++) { + valueList[i] = sortedValues[i]; + } + delete[] sortedValues; } void Session::sortTablet(Tablet& tablet) { - /* + /* * following part of code sort the batch data by time, * so we can insert continuous data in value list to get a better performance */ - // sort to get index, and use index to sort value list - int* index = new int[tablet.rowSize]; - for (size_t i = 0; i < tablet.rowSize; i++) { - index[i] = i; - } - - sortIndexByTimestamp(index, tablet.timestamps, tablet.rowSize); - tablet.timestamps = sortList(tablet.timestamps, index, tablet.rowSize); - for (size_t i = 0; i < tablet.schemas.size(); i++) { - TSDataType::TSDataType dataType = tablet.schemas[i].second; - switch (dataType) { - case TSDataType::BOOLEAN: { - sortValuesList((bool*)(tablet.values[i]), index, tablet.rowSize); - break; - } - case TSDataType::INT32: { - sortValuesList((int*)(tablet.values[i]), index, tablet.rowSize); - break; - } - case TSDataType::DATE: { - sortValuesList((boost::gregorian::date*)(tablet.values[i]), index, tablet.rowSize); - break; - } - case TSDataType::TIMESTAMP: - case TSDataType::INT64: { - sortValuesList((int64_t*)(tablet.values[i]), index, tablet.rowSize); - break; - } - case TSDataType::FLOAT: { - sortValuesList((float*)(tablet.values[i]), index, tablet.rowSize); - break; - } - case TSDataType::DOUBLE: { - sortValuesList((double*)(tablet.values[i]), index, tablet.rowSize); - break; - } - case TSDataType::STRING: - case TSDataType::BLOB: - case TSDataType::OBJECT: - case TSDataType::TEXT: { - sortValuesList((string*)(tablet.values[i]), index, tablet.rowSize); - break; - } - default: - throw UnSupportedDataTypeException(string("Data type ") + to_string(dataType) + " is not supported."); - } + // sort to get index, and use index to sort value list + int* index = new int[tablet.rowSize]; + for (size_t i = 0; i < tablet.rowSize; i++) { + index[i] = i; + } + + sortIndexByTimestamp(index, tablet.timestamps, tablet.rowSize); + tablet.timestamps = sortList(tablet.timestamps, index, tablet.rowSize); + for (size_t i = 0; i < tablet.schemas.size(); i++) { + TSDataType::TSDataType dataType = tablet.schemas[i].second; + switch (dataType) { + case TSDataType::BOOLEAN: { + sortValuesList((bool*)(tablet.values[i]), index, tablet.rowSize); + break; + } + case TSDataType::INT32: { + sortValuesList((int*)(tablet.values[i]), index, tablet.rowSize); + break; + } + case TSDataType::DATE: { + sortValuesList((boost::gregorian::date*)(tablet.values[i]), index, tablet.rowSize); + break; + } + case TSDataType::TIMESTAMP: + case TSDataType::INT64: { + sortValuesList((int64_t*)(tablet.values[i]), index, tablet.rowSize); + break; + } + case TSDataType::FLOAT: { + sortValuesList((float*)(tablet.values[i]), index, tablet.rowSize); + break; + } + case TSDataType::DOUBLE: { + sortValuesList((double*)(tablet.values[i]), index, tablet.rowSize); + break; + } + case TSDataType::STRING: + case TSDataType::BLOB: + case TSDataType::OBJECT: + case TSDataType::TEXT: { + sortValuesList((string*)(tablet.values[i]), index, tablet.rowSize); + break; } + default: + throw UnSupportedDataTypeException(string("Data type ") + to_string(dataType) + + " is not supported."); + } + } - delete[] index; + delete[] index; } void Session::sortIndexByTimestamp(int* index, std::vector& timestamps, int length) { - if (length <= 1) { - return; - } + if (length <= 1) { + return; + } - TsCompare tsCompareObj(timestamps); - std::sort(&index[0], &index[length], tsCompareObj); + TsCompare tsCompareObj(timestamps); + std::sort(&index[0], &index[length], tsCompareObj); } /** * Append value into buffer in Big Endian order to comply with IoTDB server */ void Session::appendValues(string& buffer, const char* value, int size) { - static bool hasCheckedEndianFlag = false; - static bool localCpuIsBigEndian = false; - if (!hasCheckedEndianFlag) { - hasCheckedEndianFlag = true; - int chk = 0x0201; //used to distinguish CPU's type (BigEndian or LittleEndian) - localCpuIsBigEndian = (0x01 != *(char*)(&chk)); - } - - if (localCpuIsBigEndian) { - buffer.append(value, size); - } - else { - for (int i = size - 1; i >= 0; i--) { - buffer.append(value + i, 1); - } - } -} - -void -Session::putValuesIntoBuffer(const vector& types, const vector& values, string& buf) { - int32_t date; - for (size_t i = 0; i < values.size(); i++) { - int8_t typeNum = getDataTypeNumber(types[i]); - buf.append((char*)(&typeNum), sizeof(int8_t)); - switch (types[i]) { - case TSDataType::BOOLEAN: - buf.append(values[i], 1); - break; - case TSDataType::INT32: - appendValues(buf, values[i], sizeof(int32_t)); - break; - case TSDataType::DATE: - date = parseDateExpressionToInt(*(boost::gregorian::date*)values[i]); - appendValues(buf, (char*)&date, sizeof(int32_t)); - break; - case TSDataType::TIMESTAMP: - case TSDataType::INT64: - appendValues(buf, values[i], sizeof(int64_t)); - break; - case TSDataType::FLOAT: - appendValues(buf, values[i], sizeof(float)); - break; - case TSDataType::DOUBLE: - appendValues(buf, values[i], sizeof(double)); - break; - case TSDataType::STRING: - case TSDataType::BLOB: - case TSDataType::OBJECT: - case TSDataType::TEXT: { - int32_t len = (uint32_t)strlen(values[i]); - appendValues(buf, (char*)(&len), sizeof(uint32_t)); - // no need to change the byte order of string value - buf.append(values[i], len); - break; - } - default: - break; - } - } -} - -int8_t Session::getDataTypeNumber(TSDataType::TSDataType type) { - switch (type) { + static bool hasCheckedEndianFlag = false; + static bool localCpuIsBigEndian = false; + if (!hasCheckedEndianFlag) { + hasCheckedEndianFlag = true; + int chk = 0x0201; //used to distinguish CPU's type (BigEndian or LittleEndian) + localCpuIsBigEndian = (0x01 != *(char*)(&chk)); + } + + if (localCpuIsBigEndian) { + buffer.append(value, size); + } else { + for (int i = size - 1; i >= 0; i--) { + buffer.append(value + i, 1); + } + } +} + +void Session::putValuesIntoBuffer(const vector& types, + const vector& values, string& buf) { + int32_t date; + for (size_t i = 0; i < values.size(); i++) { + int8_t typeNum = getDataTypeNumber(types[i]); + buf.append((char*)(&typeNum), sizeof(int8_t)); + switch (types[i]) { case TSDataType::BOOLEAN: - return 0; + buf.append(values[i], 1); + break; case TSDataType::INT32: - return 1; + appendValues(buf, values[i], sizeof(int32_t)); + break; + case TSDataType::DATE: + date = parseDateExpressionToInt(*(boost::gregorian::date*)values[i]); + appendValues(buf, (char*)&date, sizeof(int32_t)); + break; + case TSDataType::TIMESTAMP: case TSDataType::INT64: - return 2; + appendValues(buf, values[i], sizeof(int64_t)); + break; case TSDataType::FLOAT: - return 3; + appendValues(buf, values[i], sizeof(float)); + break; case TSDataType::DOUBLE: - return 4; - case TSDataType::TEXT: - return 5; - case TSDataType::TIMESTAMP: - return 8; - case TSDataType::DATE: - return 9; - case TSDataType::BLOB: - return 10; + appendValues(buf, values[i], sizeof(double)); + break; case TSDataType::STRING: - return 11; + case TSDataType::BLOB: case TSDataType::OBJECT: - return 12; + case TSDataType::TEXT: { + int32_t len = (uint32_t)strlen(values[i]); + appendValues(buf, (char*)(&len), sizeof(uint32_t)); + // no need to change the byte order of string value + buf.append(values[i], len); + break; + } default: - return -1; + break; } + } +} + +int8_t Session::getDataTypeNumber(TSDataType::TSDataType type) { + switch (type) { + case TSDataType::BOOLEAN: + return 0; + case TSDataType::INT32: + return 1; + case TSDataType::INT64: + return 2; + case TSDataType::FLOAT: + return 3; + case TSDataType::DOUBLE: + return 4; + case TSDataType::TEXT: + return 5; + case TSDataType::TIMESTAMP: + return 8; + case TSDataType::DATE: + return 9; + case TSDataType::BLOB: + return 10; + case TSDataType::STRING: + return 11; + case TSDataType::OBJECT: + return 12; + default: + return -1; + } } string Session::getVersionString(Version::Version version) { - switch (version) { - case Version::V_0_12: - return "V_0_12"; - case Version::V_0_13: - return "V_0_13"; - case Version::V_1_0: - return "V_1_0"; - default: - return "V_0_12"; - } + switch (version) { + case Version::V_0_12: + return "V_0_12"; + case Version::V_0_13: + return "V_0_13"; + case Version::V_1_0: + return "V_1_0"; + default: + return "V_0_12"; + } } void Session::initZoneId() { - if (!zoneId_.empty()) { - return; - } - - time_t ts = 0; - struct tm tmv; -#if defined(_WIN64) || defined (WIN32) || defined (_WIN32) - localtime_s(&tmv, &ts); + if (!zoneId_.empty()) { + return; + } + + time_t ts = 0; + struct tm tmv; +#if defined(_WIN64) || defined(WIN32) || defined(_WIN32) + localtime_s(&tmv, &ts); #else - localtime_r(&ts, &tmv); + localtime_r(&ts, &tmv); #endif - char zoneStr[32]; - strftime(zoneStr, sizeof(zoneStr), "%z", &tmv); - zoneId_ = zoneStr; + char zoneStr[32]; + strftime(zoneStr, sizeof(zoneStr), "%z", &tmv); + zoneId_ = zoneStr; } void Session::initNodesSupplier(const std::vector& nodeUrls) { - std::vector endPoints; - std::unordered_set uniqueEndpoints; - - if (nodeUrls.empty() && host_.empty()) { - throw IoTDBException("No available nodes"); - } - - // Process provided node URLs - if (!nodeUrls.empty()) { - for (auto& url : nodeUrls) { - try { - TEndPoint endPoint = UrlUtils::parseTEndPointIpv4AndIpv6Url(url); - if (endPoint.port == 0) continue; // Skip invalid endpoints - - std::string endpointKey = endPoint.ip + ":" + std::to_string(endPoint.port); - if (uniqueEndpoints.find(endpointKey) == uniqueEndpoints.end()) { - endPoints.emplace_back(std::move(endPoint)); - uniqueEndpoints.insert(std::move(endpointKey)); - } - } catch (...) { - continue; // Skip malformed URLs - } - } - } - - // Fallback to local endpoint if no valid endpoints found - if (endPoints.empty()) { - if (host_.empty() || rpcPort_ == 0) { - throw IoTDBException("No valid endpoints available"); - } - TEndPoint endPoint; - endPoint.__set_ip(host_); - endPoint.__set_port(rpcPort_); - endPoints.emplace_back(std::move(endPoint)); - } - - if (enableAutoFetch_) { - nodesSupplier_ = NodesSupplier::create(endPoints, username_, password_, useSSL_, trustCertFilePath_); - } - else { - nodesSupplier_ = make_shared(endPoints); - } + std::vector endPoints; + std::unordered_set uniqueEndpoints; + + if (nodeUrls.empty() && host_.empty()) { + throw IoTDBException("No available nodes"); + } + + // Process provided node URLs + if (!nodeUrls.empty()) { + for (auto& url : nodeUrls) { + try { + TEndPoint endPoint = UrlUtils::parseTEndPointIpv4AndIpv6Url(url); + if (endPoint.port == 0) + continue; // Skip invalid endpoints + + std::string endpointKey = endPoint.ip + ":" + std::to_string(endPoint.port); + if (uniqueEndpoints.find(endpointKey) == uniqueEndpoints.end()) { + endPoints.emplace_back(std::move(endPoint)); + uniqueEndpoints.insert(std::move(endpointKey)); + } + } catch (...) { + continue; // Skip malformed URLs + } + } + } + + // Fallback to local endpoint if no valid endpoints found + if (endPoints.empty()) { + if (host_.empty() || rpcPort_ == 0) { + throw IoTDBException("No valid endpoints available"); + } + TEndPoint endPoint; + endPoint.__set_ip(host_); + endPoint.__set_port(rpcPort_); + endPoints.emplace_back(std::move(endPoint)); + } + + if (enableAutoFetch_) { + nodesSupplier_ = + NodesSupplier::create(endPoints, username_, password_, useSSL_, trustCertFilePath_); + } else { + nodesSupplier_ = make_shared(endPoints); + } } void Session::initDefaultSessionConnection() { - // Try all endpoints from supplier until a connection is established. - auto endpoints = nodesSupplier_->getEndPointList(); - bool connected = false; - - for (const auto& endpoint : endpoints) { - try { - host_ = endpoint.ip; - rpcPort_ = endpoint.port; - - defaultEndPoint_.__set_ip(host_); - defaultEndPoint_.__set_port(rpcPort_); - - defaultSessionConnection_ = std::make_shared( - this, defaultEndPoint_, zoneId_, nodesSupplier_, fetchSize_, - 3, - 500, connectTimeoutMs_, - sqlDialect_, database_); - - connected = true; - break; - } catch (const IoTDBException& e) { - log_debug(e.what()); - throw; - } catch (const std::exception& e) { - log_warn(e.what()); - } - } + // Try all endpoints from supplier until a connection is established. + auto endpoints = nodesSupplier_->getEndPointList(); + bool connected = false; + + for (const auto& endpoint : endpoints) { + try { + host_ = endpoint.ip; + rpcPort_ = endpoint.port; - if (!connected) { - throw std::runtime_error("No available node to establish SessionConnection."); + defaultEndPoint_.__set_ip(host_); + defaultEndPoint_.__set_port(rpcPort_); + + defaultSessionConnection_ = std::make_shared( + this, defaultEndPoint_, zoneId_, nodesSupplier_, fetchSize_, 3, 500, connectTimeoutMs_, + sqlDialect_, database_); + + connected = true; + break; + } catch (const IoTDBException& e) { + log_debug(e.what()); + throw; + } catch (const std::exception& e) { + log_warn(e.what()); } + } + + if (!connected) { + throw std::runtime_error("No available node to establish SessionConnection."); + } } void Session::insertStringRecordsWithLeaderCache(vector deviceIds, vector times, vector> measurementsList, - vector> valuesList, bool isAligned) { - std::unordered_map, TSInsertStringRecordsReq> recordsGroup; - for (int i = 0; i < deviceIds.size(); i++) { - auto connection = getSessionConnection(deviceIds[i]); - if (recordsGroup.find(connection) == recordsGroup.end()) { - TSInsertStringRecordsReq request; - std::vector emptyPrefixPaths; - std::vector> emptyMeasurementsList; - vector> emptyValuesList; - std::vector emptyTimestamps; - request.__set_isAligned(isAligned); - request.__set_prefixPaths(emptyPrefixPaths); - request.__set_timestamps(emptyTimestamps); - request.__set_measurementsList(emptyMeasurementsList); - request.__set_valuesList(emptyValuesList); - recordsGroup.insert(make_pair(connection, request)); - } - TSInsertStringRecordsReq& existingReq = recordsGroup[connection]; - existingReq.prefixPaths.emplace_back(deviceIds[i]); - existingReq.timestamps.emplace_back(times[i]); - existingReq.measurementsList.emplace_back(measurementsList[i]); - existingReq.valuesList.emplace_back(valuesList[i]); - } - std::function, const TSInsertStringRecordsReq&)> consumer = - [](const std::shared_ptr& c, const TSInsertStringRecordsReq& r) { - c->insertStringRecords(r); - }; - if (recordsGroup.size() == 1) { - insertOnce(recordsGroup, consumer); - } - else { - insertByGroup(recordsGroup, consumer); - } + vector> valuesList, + bool isAligned) { + std::unordered_map, TSInsertStringRecordsReq> recordsGroup; + for (int i = 0; i < deviceIds.size(); i++) { + auto connection = getSessionConnection(deviceIds[i]); + if (recordsGroup.find(connection) == recordsGroup.end()) { + TSInsertStringRecordsReq request; + std::vector emptyPrefixPaths; + std::vector> emptyMeasurementsList; + vector> emptyValuesList; + std::vector emptyTimestamps; + request.__set_isAligned(isAligned); + request.__set_prefixPaths(emptyPrefixPaths); + request.__set_timestamps(emptyTimestamps); + request.__set_measurementsList(emptyMeasurementsList); + request.__set_valuesList(emptyValuesList); + recordsGroup.insert(make_pair(connection, request)); + } + TSInsertStringRecordsReq& existingReq = recordsGroup[connection]; + existingReq.prefixPaths.emplace_back(deviceIds[i]); + existingReq.timestamps.emplace_back(times[i]); + existingReq.measurementsList.emplace_back(measurementsList[i]); + existingReq.valuesList.emplace_back(valuesList[i]); + } + std::function, const TSInsertStringRecordsReq&)> + consumer = [](const std::shared_ptr& c, + const TSInsertStringRecordsReq& r) { c->insertStringRecords(r); }; + if (recordsGroup.size() == 1) { + insertOnce(recordsGroup, consumer); + } else { + insertByGroup(recordsGroup, consumer); + } } void Session::insertRecordsWithLeaderCache(vector deviceIds, vector times, vector> measurementsList, const vector>& typesList, vector> valuesList, bool isAligned) { - std::unordered_map, TSInsertRecordsReq> recordsGroup; - for (int i = 0; i < deviceIds.size(); i++) { - auto connection = getSessionConnection(deviceIds[i]); - if (recordsGroup.find(connection) == recordsGroup.end()) { - TSInsertRecordsReq request; - std::vector emptyPrefixPaths; - std::vector> emptyMeasurementsList; - std::vector emptyValuesList; - std::vector emptyTimestamps; - request.__set_isAligned(isAligned); - request.__set_prefixPaths(emptyPrefixPaths); - request.__set_timestamps(emptyTimestamps); - request.__set_measurementsList(emptyMeasurementsList); - request.__set_valuesList(emptyValuesList); - recordsGroup.insert(make_pair(connection, request)); - } - TSInsertRecordsReq& existingReq = recordsGroup[connection]; - existingReq.prefixPaths.emplace_back(deviceIds[i]); - existingReq.timestamps.emplace_back(times[i]); - existingReq.measurementsList.emplace_back(measurementsList[i]); - vector bufferList; - string buffer; - putValuesIntoBuffer(typesList[i], valuesList[i], buffer); - existingReq.valuesList.emplace_back(buffer); - recordsGroup[connection] = existingReq; - } - std::function, const TSInsertRecordsReq&)> consumer = - [](const std::shared_ptr& c, const TSInsertRecordsReq& r) { + std::unordered_map, TSInsertRecordsReq> recordsGroup; + for (int i = 0; i < deviceIds.size(); i++) { + auto connection = getSessionConnection(deviceIds[i]); + if (recordsGroup.find(connection) == recordsGroup.end()) { + TSInsertRecordsReq request; + std::vector emptyPrefixPaths; + std::vector> emptyMeasurementsList; + std::vector emptyValuesList; + std::vector emptyTimestamps; + request.__set_isAligned(isAligned); + request.__set_prefixPaths(emptyPrefixPaths); + request.__set_timestamps(emptyTimestamps); + request.__set_measurementsList(emptyMeasurementsList); + request.__set_valuesList(emptyValuesList); + recordsGroup.insert(make_pair(connection, request)); + } + TSInsertRecordsReq& existingReq = recordsGroup[connection]; + existingReq.prefixPaths.emplace_back(deviceIds[i]); + existingReq.timestamps.emplace_back(times[i]); + existingReq.measurementsList.emplace_back(measurementsList[i]); + vector bufferList; + string buffer; + putValuesIntoBuffer(typesList[i], valuesList[i], buffer); + existingReq.valuesList.emplace_back(buffer); + recordsGroup[connection] = existingReq; + } + std::function, const TSInsertRecordsReq&)> consumer = + [](const std::shared_ptr& c, const TSInsertRecordsReq& r) { c->insertRecords(r); - }; - if (recordsGroup.size() == 1) { - insertOnce(recordsGroup, consumer); - } - else { - insertByGroup(recordsGroup, consumer); - } -} - -void Session::insertTabletsWithLeaderCache(unordered_map tablets, bool sorted, bool isAligned) { - std::unordered_map, TSInsertTabletsReq> tabletsGroup; - if (tablets.empty()) { - throw BatchExecutionException("No tablet is inserting!"); - } - for (const auto& item : tablets) { - if (isAligned != item.second->isAligned) { - throw BatchExecutionException("The tablets should be all aligned or non-aligned!"); - } - if (!checkSorted(*(item.second))) { - sortTablet(*(item.second)); - } - auto deviceId = item.first; - auto tablet = item.second; - auto connection = getSessionConnection(deviceId); - auto it = tabletsGroup.find(connection); - if (it == tabletsGroup.end()) { - TSInsertTabletsReq request; - tabletsGroup[connection] = request; - } - TSInsertTabletsReq& existingReq = tabletsGroup[connection]; - existingReq.prefixPaths.emplace_back(tablet->deviceId); - existingReq.timestampsList.emplace_back(move(SessionUtils::getTime(*tablet))); - existingReq.valuesList.emplace_back(move(SessionUtils::getValue(*tablet))); - existingReq.sizeList.emplace_back(tablet->rowSize); - vector dataTypes; - vector measurements; - for (pair schema : tablet->schemas) { - measurements.push_back(schema.first); - dataTypes.push_back(schema.second); - } - existingReq.measurementsList.emplace_back(measurements); - existingReq.typesList.emplace_back(dataTypes); - } - - std::function, const TSInsertTabletsReq&)> consumer = - [](const std::shared_ptr& c, const TSInsertTabletsReq& r) { + }; + if (recordsGroup.size() == 1) { + insertOnce(recordsGroup, consumer); + } else { + insertByGroup(recordsGroup, consumer); + } +} + +void Session::insertTabletsWithLeaderCache(unordered_map tablets, bool sorted, + bool isAligned) { + std::unordered_map, TSInsertTabletsReq> tabletsGroup; + if (tablets.empty()) { + throw BatchExecutionException("No tablet is inserting!"); + } + for (const auto& item : tablets) { + if (isAligned != item.second->isAligned) { + throw BatchExecutionException("The tablets should be all aligned or non-aligned!"); + } + if (!checkSorted(*(item.second))) { + sortTablet(*(item.second)); + } + auto deviceId = item.first; + auto tablet = item.second; + auto connection = getSessionConnection(deviceId); + auto it = tabletsGroup.find(connection); + if (it == tabletsGroup.end()) { + TSInsertTabletsReq request; + tabletsGroup[connection] = request; + } + TSInsertTabletsReq& existingReq = tabletsGroup[connection]; + existingReq.prefixPaths.emplace_back(tablet->deviceId); + existingReq.timestampsList.emplace_back(move(SessionUtils::getTime(*tablet))); + existingReq.valuesList.emplace_back(move(SessionUtils::getValue(*tablet))); + existingReq.sizeList.emplace_back(tablet->rowSize); + vector dataTypes; + vector measurements; + for (pair schema : tablet->schemas) { + measurements.push_back(schema.first); + dataTypes.push_back(schema.second); + } + existingReq.measurementsList.emplace_back(measurements); + existingReq.typesList.emplace_back(dataTypes); + } + + std::function, const TSInsertTabletsReq&)> consumer = + [](const std::shared_ptr& c, const TSInsertTabletsReq& r) { c->insertTablets(r); - }; - if (tabletsGroup.size() == 1) { - insertOnce(tabletsGroup, consumer); - } - else { - insertByGroup(tabletsGroup, consumer); - } + }; + if (tabletsGroup.size() == 1) { + insertOnce(tabletsGroup, consumer); + } else { + insertByGroup(tabletsGroup, consumer); + } } void Session::open() { - open(false, DEFAULT_TIMEOUT_MS); + open(false, DEFAULT_TIMEOUT_MS); } void Session::open(bool enableRPCCompression) { - open(enableRPCCompression, DEFAULT_TIMEOUT_MS); + open(enableRPCCompression, DEFAULT_TIMEOUT_MS); } void Session::open(bool enableRPCCompression, int connectionTimeoutInMs) { - if (!isClosed_) { - return; - } + if (!isClosed_) { + return; + } - try { - initDefaultSessionConnection(); - } - catch (const exception& e) { - log_debug(e.what()); - throw IoTDBException(e.what()); - } - zoneId_ = defaultSessionConnection_->zoneId; + try { + initDefaultSessionConnection(); + } catch (const exception& e) { + log_debug(e.what()); + throw IoTDBException(e.what()); + } + zoneId_ = defaultSessionConnection_->zoneId; - if (enableRedirection_) { - endPointToSessionConnection.insert(make_pair(defaultEndPoint_, defaultSessionConnection_)); - } + if (enableRedirection_) { + endPointToSessionConnection.insert(make_pair(defaultEndPoint_, defaultSessionConnection_)); + } - isClosed_ = false; + isClosed_ = false; } - void Session::close() { - if (isClosed_) { - return; - } - isClosed_ = true; + if (isClosed_) { + return; + } + isClosed_ = true; } - -void Session::insertRecord(const string& deviceId, int64_t time, - const vector& measurements, +void Session::insertRecord(const string& deviceId, int64_t time, const vector& measurements, const vector& values) { - TSInsertStringRecordReq req; - req.__set_prefixPath(deviceId); - req.__set_timestamp(time); - req.__set_measurements(measurements); - req.__set_values(values); - req.__set_isAligned(false); - try { - getSessionConnection(deviceId)->insertStringRecord(req); - } - catch (RedirectException& e) { - handleRedirection(deviceId, e.endPoint); - } catch (const IoTDBConnectionException& e) { - if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { - deviceIdToEndpoint.erase(deviceId); - try { - defaultSessionConnection_->insertStringRecord(req); - } - catch (RedirectException& e) { - } - } - else { - throw e; - } - } -} - -void Session::insertRecord(const string& deviceId, int64_t time, - const vector& measurements, + TSInsertStringRecordReq req; + req.__set_prefixPath(deviceId); + req.__set_timestamp(time); + req.__set_measurements(measurements); + req.__set_values(values); + req.__set_isAligned(false); + try { + getSessionConnection(deviceId)->insertStringRecord(req); + } catch (RedirectException& e) { + handleRedirection(deviceId, e.endPoint); + } catch (const IoTDBConnectionException& e) { + if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { + deviceIdToEndpoint.erase(deviceId); + try { + defaultSessionConnection_->insertStringRecord(req); + } catch (RedirectException& e) { + } + } else { + throw e; + } + } +} + +void Session::insertRecord(const string& deviceId, int64_t time, const vector& measurements, const vector& types, const vector& values) { - TSInsertRecordReq req; - req.__set_prefixPath(deviceId); - req.__set_timestamp(time); - req.__set_measurements(measurements); - string buffer; - putValuesIntoBuffer(types, values, buffer); - req.__set_values(buffer); - req.__set_isAligned(false); - try { - getSessionConnection(deviceId)->insertRecord(req); - } - catch (RedirectException& e) { - handleRedirection(deviceId, e.endPoint); - } catch (const IoTDBConnectionException& e) { - if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { - deviceIdToEndpoint.erase(deviceId); - try { - defaultSessionConnection_->insertRecord(req); - } - catch (RedirectException& e) { - } - } - else { - throw e; - } - } + TSInsertRecordReq req; + req.__set_prefixPath(deviceId); + req.__set_timestamp(time); + req.__set_measurements(measurements); + string buffer; + putValuesIntoBuffer(types, values, buffer); + req.__set_values(buffer); + req.__set_isAligned(false); + try { + getSessionConnection(deviceId)->insertRecord(req); + } catch (RedirectException& e) { + handleRedirection(deviceId, e.endPoint); + } catch (const IoTDBConnectionException& e) { + if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { + deviceIdToEndpoint.erase(deviceId); + try { + defaultSessionConnection_->insertRecord(req); + } catch (RedirectException& e) { + } + } else { + throw e; + } + } } void Session::insertAlignedRecord(const string& deviceId, int64_t time, const vector& measurements, const vector& values) { - TSInsertStringRecordReq req; - req.__set_prefixPath(deviceId); - req.__set_timestamp(time); - req.__set_measurements(measurements); - req.__set_values(values); - req.__set_isAligned(true); - try { - getSessionConnection(deviceId)->insertStringRecord(req); - } - catch (RedirectException& e) { - handleRedirection(deviceId, e.endPoint); - } catch (const IoTDBConnectionException& e) { - if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { - deviceIdToEndpoint.erase(deviceId); - try { - defaultSessionConnection_->insertStringRecord(req); - } - catch (RedirectException& e) { - } - } - else { - throw e; - } - } + TSInsertStringRecordReq req; + req.__set_prefixPath(deviceId); + req.__set_timestamp(time); + req.__set_measurements(measurements); + req.__set_values(values); + req.__set_isAligned(true); + try { + getSessionConnection(deviceId)->insertStringRecord(req); + } catch (RedirectException& e) { + handleRedirection(deviceId, e.endPoint); + } catch (const IoTDBConnectionException& e) { + if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { + deviceIdToEndpoint.erase(deviceId); + try { + defaultSessionConnection_->insertStringRecord(req); + } catch (RedirectException& e) { + } + } else { + throw e; + } + } } void Session::insertAlignedRecord(const string& deviceId, int64_t time, const vector& measurements, const vector& types, const vector& values) { - TSInsertRecordReq req; - req.__set_prefixPath(deviceId); - req.__set_timestamp(time); - req.__set_measurements(measurements); - string buffer; - putValuesIntoBuffer(types, values, buffer); - req.__set_values(buffer); - req.__set_isAligned(false); - try { - getSessionConnection(deviceId)->insertRecord(req); - } - catch (RedirectException& e) { - handleRedirection(deviceId, e.endPoint); - } catch (const IoTDBConnectionException& e) { - if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { - deviceIdToEndpoint.erase(deviceId); - try { - defaultSessionConnection_->insertRecord(req); - } - catch (RedirectException& e) { - } - } - else { - throw e; - } - } -} - -void Session::insertRecords(const vector& deviceIds, - const vector& times, + TSInsertRecordReq req; + req.__set_prefixPath(deviceId); + req.__set_timestamp(time); + req.__set_measurements(measurements); + string buffer; + putValuesIntoBuffer(types, values, buffer); + req.__set_values(buffer); + req.__set_isAligned(false); + try { + getSessionConnection(deviceId)->insertRecord(req); + } catch (RedirectException& e) { + handleRedirection(deviceId, e.endPoint); + } catch (const IoTDBConnectionException& e) { + if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { + deviceIdToEndpoint.erase(deviceId); + try { + defaultSessionConnection_->insertRecord(req); + } catch (RedirectException& e) { + } + } else { + throw e; + } + } +} + +void Session::insertRecords(const vector& deviceIds, const vector& times, const vector>& measurementsList, const vector>& valuesList) { - size_t len = deviceIds.size(); - if (len != times.size() || len != measurementsList.size() || len != valuesList.size()) { - logic_error e("deviceIds, times, measurementsList and valuesList's size should be equal"); - throw exception(e); - } - - if (enableRedirection_) { - insertStringRecordsWithLeaderCache(deviceIds, times, measurementsList, valuesList, false); - } - else { - TSInsertStringRecordsReq request; - request.__set_prefixPaths(deviceIds); - request.__set_timestamps(times); - request.__set_measurementsList(measurementsList); - request.__set_valuesList(valuesList); - request.__set_isAligned(false); - try { - defaultSessionConnection_->insertStringRecords(request); - } - catch (RedirectException& e) { - } + size_t len = deviceIds.size(); + if (len != times.size() || len != measurementsList.size() || len != valuesList.size()) { + logic_error e("deviceIds, times, measurementsList and valuesList's size should be equal"); + throw exception(e); + } + + if (enableRedirection_) { + insertStringRecordsWithLeaderCache(deviceIds, times, measurementsList, valuesList, false); + } else { + TSInsertStringRecordsReq request; + request.__set_prefixPaths(deviceIds); + request.__set_timestamps(times); + request.__set_measurementsList(measurementsList); + request.__set_valuesList(valuesList); + request.__set_isAligned(false); + try { + defaultSessionConnection_->insertStringRecords(request); + } catch (RedirectException& e) { } + } } -void Session::insertRecords(const vector& deviceIds, - const vector& times, +void Session::insertRecords(const vector& deviceIds, const vector& times, const vector>& measurementsList, const vector>& typesList, const vector>& valuesList) { - size_t len = deviceIds.size(); - if (len != times.size() || len != measurementsList.size() || len != valuesList.size()) { - logic_error e("deviceIds, times, measurementsList and valuesList's size should be equal"); - throw exception(e); - } - - if (enableRedirection_) { - insertRecordsWithLeaderCache(deviceIds, times, measurementsList, typesList, valuesList, false); - } - else { - TSInsertRecordsReq request; - request.__set_prefixPaths(deviceIds); - request.__set_timestamps(times); - request.__set_measurementsList(measurementsList); - vector bufferList; - for (size_t i = 0; i < valuesList.size(); i++) { - string buffer; - putValuesIntoBuffer(typesList[i], valuesList[i], buffer); - bufferList.push_back(buffer); - } - request.__set_valuesList(bufferList); - request.__set_isAligned(false); - try { - defaultSessionConnection_->insertRecords(request); - } - catch (RedirectException& e) { - } + size_t len = deviceIds.size(); + if (len != times.size() || len != measurementsList.size() || len != valuesList.size()) { + logic_error e("deviceIds, times, measurementsList and valuesList's size should be equal"); + throw exception(e); + } + + if (enableRedirection_) { + insertRecordsWithLeaderCache(deviceIds, times, measurementsList, typesList, valuesList, false); + } else { + TSInsertRecordsReq request; + request.__set_prefixPaths(deviceIds); + request.__set_timestamps(times); + request.__set_measurementsList(measurementsList); + vector bufferList; + for (size_t i = 0; i < valuesList.size(); i++) { + string buffer; + putValuesIntoBuffer(typesList[i], valuesList[i], buffer); + bufferList.push_back(buffer); } -} - -void Session::insertAlignedRecords(const vector& deviceIds, - const vector& times, - const vector>& measurementsList, - const vector>& valuesList) { - size_t len = deviceIds.size(); - if (len != times.size() || len != measurementsList.size() || len != valuesList.size()) { - logic_error e("deviceIds, times, measurementsList and valuesList's size should be equal"); - throw exception(e); - } - - if (enableRedirection_) { - insertStringRecordsWithLeaderCache(deviceIds, times, measurementsList, valuesList, true); - } - else { - TSInsertStringRecordsReq request; - request.__set_prefixPaths(deviceIds); - request.__set_timestamps(times); - request.__set_measurementsList(measurementsList); - request.__set_valuesList(valuesList); - request.__set_isAligned(true); - try { - defaultSessionConnection_->insertStringRecords(request); - } - catch (RedirectException& e) { - } + request.__set_valuesList(bufferList); + request.__set_isAligned(false); + try { + defaultSessionConnection_->insertRecords(request); + } catch (RedirectException& e) { } + } } -void Session::insertAlignedRecords(const vector& deviceIds, - const vector& times, +void Session::insertAlignedRecords(const vector& deviceIds, const vector& times, const vector>& measurementsList, - const vector>& typesList, - const vector>& valuesList) { - size_t len = deviceIds.size(); - if (len != times.size() || len != measurementsList.size() || len != valuesList.size()) { - logic_error e("deviceIds, times, measurementsList and valuesList's size should be equal"); - throw exception(e); - } - - if (enableRedirection_) { - insertRecordsWithLeaderCache(deviceIds, times, measurementsList, typesList, valuesList, true); - } - else { - TSInsertRecordsReq request; - request.__set_prefixPaths(deviceIds); - request.__set_timestamps(times); - request.__set_measurementsList(measurementsList); - vector bufferList; - for (size_t i = 0; i < valuesList.size(); i++) { - string buffer; - putValuesIntoBuffer(typesList[i], valuesList[i], buffer); - bufferList.push_back(buffer); - } - request.__set_valuesList(bufferList); - request.__set_isAligned(false); - try { - defaultSessionConnection_->insertRecords(request); - } - catch (RedirectException& e) { - } + const vector>& valuesList) { + size_t len = deviceIds.size(); + if (len != times.size() || len != measurementsList.size() || len != valuesList.size()) { + logic_error e("deviceIds, times, measurementsList and valuesList's size should be equal"); + throw exception(e); + } + + if (enableRedirection_) { + insertStringRecordsWithLeaderCache(deviceIds, times, measurementsList, valuesList, true); + } else { + TSInsertStringRecordsReq request; + request.__set_prefixPaths(deviceIds); + request.__set_timestamps(times); + request.__set_measurementsList(measurementsList); + request.__set_valuesList(valuesList); + request.__set_isAligned(true); + try { + defaultSessionConnection_->insertStringRecords(request); + } catch (RedirectException& e) { } + } } -void Session::insertRecordsOfOneDevice(const string& deviceId, - vector& times, - vector>& measurementsList, - vector>& typesList, - vector>& valuesList) { - insertRecordsOfOneDevice(deviceId, times, measurementsList, typesList, valuesList, false); -} - -void Session::insertRecordsOfOneDevice(const string& deviceId, - vector& times, - vector>& measurementsList, - vector>& typesList, - vector>& valuesList, - bool sorted) { - if (!checkSorted(times)) { - int* index = new int[times.size()]; - for (size_t i = 0; i < times.size(); i++) { - index[i] = (int)i; - } - - sortIndexByTimestamp(index, times, (int)(times.size())); - times = sortList(times, index, (int)(times.size())); - measurementsList = sortList(measurementsList, index, (int)(times.size())); - typesList = sortList(typesList, index, (int)(times.size())); - valuesList = sortList(valuesList, index, (int)(times.size())); - delete[] index; - } - TSInsertRecordsOfOneDeviceReq request; - request.__set_prefixPath(deviceId); +void Session::insertAlignedRecords(const vector& deviceIds, const vector& times, + const vector>& measurementsList, + const vector>& typesList, + const vector>& valuesList) { + size_t len = deviceIds.size(); + if (len != times.size() || len != measurementsList.size() || len != valuesList.size()) { + logic_error e("deviceIds, times, measurementsList and valuesList's size should be equal"); + throw exception(e); + } + + if (enableRedirection_) { + insertRecordsWithLeaderCache(deviceIds, times, measurementsList, typesList, valuesList, true); + } else { + TSInsertRecordsReq request; + request.__set_prefixPaths(deviceIds); request.__set_timestamps(times); request.__set_measurementsList(measurementsList); vector bufferList; for (size_t i = 0; i < valuesList.size(); i++) { - string buffer; - putValuesIntoBuffer(typesList[i], valuesList[i], buffer); - bufferList.push_back(buffer); + string buffer; + putValuesIntoBuffer(typesList[i], valuesList[i], buffer); + bufferList.push_back(buffer); } request.__set_valuesList(bufferList); request.__set_isAligned(false); - TSStatus respStatus; try { - getSessionConnection(deviceId)->insertRecordsOfOneDevice(request); - } - catch (RedirectException& e) { - handleRedirection(deviceId, e.endPoint); - } catch (const IoTDBConnectionException& e) { - if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { - deviceIdToEndpoint.erase(deviceId); - try { - defaultSessionConnection_->insertRecordsOfOneDevice(request); - } - catch (RedirectException& e) { - } - } - else { - throw e; - } + defaultSessionConnection_->insertRecords(request); + } catch (RedirectException& e) { } + } +} + +void Session::insertRecordsOfOneDevice(const string& deviceId, vector& times, + vector>& measurementsList, + vector>& typesList, + vector>& valuesList) { + insertRecordsOfOneDevice(deviceId, times, measurementsList, typesList, valuesList, false); } -void Session::insertAlignedRecordsOfOneDevice(const string& deviceId, - vector& times, +void Session::insertRecordsOfOneDevice(const string& deviceId, vector& times, + vector>& measurementsList, + vector>& typesList, + vector>& valuesList, bool sorted) { + if (!checkSorted(times)) { + int* index = new int[times.size()]; + for (size_t i = 0; i < times.size(); i++) { + index[i] = (int)i; + } + + sortIndexByTimestamp(index, times, (int)(times.size())); + times = sortList(times, index, (int)(times.size())); + measurementsList = sortList(measurementsList, index, (int)(times.size())); + typesList = sortList(typesList, index, (int)(times.size())); + valuesList = sortList(valuesList, index, (int)(times.size())); + delete[] index; + } + TSInsertRecordsOfOneDeviceReq request; + request.__set_prefixPath(deviceId); + request.__set_timestamps(times); + request.__set_measurementsList(measurementsList); + vector bufferList; + for (size_t i = 0; i < valuesList.size(); i++) { + string buffer; + putValuesIntoBuffer(typesList[i], valuesList[i], buffer); + bufferList.push_back(buffer); + } + request.__set_valuesList(bufferList); + request.__set_isAligned(false); + TSStatus respStatus; + try { + getSessionConnection(deviceId)->insertRecordsOfOneDevice(request); + } catch (RedirectException& e) { + handleRedirection(deviceId, e.endPoint); + } catch (const IoTDBConnectionException& e) { + if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { + deviceIdToEndpoint.erase(deviceId); + try { + defaultSessionConnection_->insertRecordsOfOneDevice(request); + } catch (RedirectException& e) { + } + } else { + throw e; + } + } +} + +void Session::insertAlignedRecordsOfOneDevice(const string& deviceId, vector& times, vector>& measurementsList, vector>& typesList, vector>& valuesList) { - insertAlignedRecordsOfOneDevice(deviceId, times, measurementsList, typesList, valuesList, false); + insertAlignedRecordsOfOneDevice(deviceId, times, measurementsList, typesList, valuesList, false); } -void Session::insertAlignedRecordsOfOneDevice(const string& deviceId, - vector& times, +void Session::insertAlignedRecordsOfOneDevice(const string& deviceId, vector& times, vector>& measurementsList, vector>& typesList, - vector>& valuesList, - bool sorted) { - if (!checkSorted(times)) { - int* index = new int[times.size()]; - for (size_t i = 0; i < times.size(); i++) { - index[i] = (int)i; - } - - sortIndexByTimestamp(index, times, (int)(times.size())); - times = sortList(times, index, (int)(times.size())); - measurementsList = sortList(measurementsList, index, (int)(times.size())); - typesList = sortList(typesList, index, (int)(times.size())); - valuesList = sortList(valuesList, index, (int)(times.size())); - delete[] index; - } - TSInsertRecordsOfOneDeviceReq request; - request.__set_prefixPath(deviceId); - request.__set_timestamps(times); - request.__set_measurementsList(measurementsList); - vector bufferList; - for (size_t i = 0; i < valuesList.size(); i++) { - string buffer; - putValuesIntoBuffer(typesList[i], valuesList[i], buffer); - bufferList.push_back(buffer); - } - request.__set_valuesList(bufferList); - request.__set_isAligned(true); - TSStatus respStatus; - try { - getSessionConnection(deviceId)->insertRecordsOfOneDevice(request); - } - catch (RedirectException& e) { - handleRedirection(deviceId, e.endPoint); - } catch (const IoTDBConnectionException& e) { - if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { - deviceIdToEndpoint.erase(deviceId); - try { - defaultSessionConnection_->insertRecordsOfOneDevice(request); - } - catch (RedirectException& e) { - } - } - else { - throw e; - } - } + vector>& valuesList, bool sorted) { + if (!checkSorted(times)) { + int* index = new int[times.size()]; + for (size_t i = 0; i < times.size(); i++) { + index[i] = (int)i; + } + + sortIndexByTimestamp(index, times, (int)(times.size())); + times = sortList(times, index, (int)(times.size())); + measurementsList = sortList(measurementsList, index, (int)(times.size())); + typesList = sortList(typesList, index, (int)(times.size())); + valuesList = sortList(valuesList, index, (int)(times.size())); + delete[] index; + } + TSInsertRecordsOfOneDeviceReq request; + request.__set_prefixPath(deviceId); + request.__set_timestamps(times); + request.__set_measurementsList(measurementsList); + vector bufferList; + for (size_t i = 0; i < valuesList.size(); i++) { + string buffer; + putValuesIntoBuffer(typesList[i], valuesList[i], buffer); + bufferList.push_back(buffer); + } + request.__set_valuesList(bufferList); + request.__set_isAligned(true); + TSStatus respStatus; + try { + getSessionConnection(deviceId)->insertRecordsOfOneDevice(request); + } catch (RedirectException& e) { + handleRedirection(deviceId, e.endPoint); + } catch (const IoTDBConnectionException& e) { + if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { + deviceIdToEndpoint.erase(deviceId); + try { + defaultSessionConnection_->insertRecordsOfOneDevice(request); + } catch (RedirectException& e) { + } + } else { + throw e; + } + } } void Session::insertTablet(Tablet& tablet) { - try { - insertTablet(tablet, false); - } - catch (const exception& e) { - log_debug(e.what()); - logic_error error(e.what()); - throw exception(error); - } + try { + insertTablet(tablet, false); + } catch (const exception& e) { + log_debug(e.what()); + logic_error error(e.what()); + throw exception(error); + } } void Session::buildInsertTabletReq(TSInsertTabletReq& request, Tablet& tablet, bool sorted) { - if ((!sorted) && !checkSorted(tablet)) { - sortTablet(tablet); - } - - request.__set_prefixPath(tablet.deviceId); - - std::vector reqMeasurements; - reqMeasurements.reserve(tablet.schemas.size()); - std::vector types; - types.reserve(tablet.schemas.size()); - for (pair schema : tablet.schemas) { - reqMeasurements.push_back(schema.first); - types.push_back(schema.second); - } - request.__set_measurements(reqMeasurements); - request.__set_types(types); - request.__set_values(SessionUtils::getValue(tablet)); - request.__set_timestamps(SessionUtils::getTime(tablet)); - request.__set_size(tablet.rowSize); - request.__set_isAligned(tablet.isAligned); + if ((!sorted) && !checkSorted(tablet)) { + sortTablet(tablet); + } + + request.__set_prefixPath(tablet.deviceId); + + std::vector reqMeasurements; + reqMeasurements.reserve(tablet.schemas.size()); + std::vector types; + types.reserve(tablet.schemas.size()); + for (pair schema : tablet.schemas) { + reqMeasurements.push_back(schema.first); + types.push_back(schema.second); + } + request.__set_measurements(reqMeasurements); + request.__set_types(types); + request.__set_values(SessionUtils::getValue(tablet)); + request.__set_timestamps(SessionUtils::getTime(tablet)); + request.__set_size(tablet.rowSize); + request.__set_isAligned(tablet.isAligned); } void Session::insertTablet(TSInsertTabletReq request) { - auto deviceId = request.prefixPath; - try { - getSessionConnection(deviceId)->insertTablet(request); - } - catch (RedirectException& e) { - handleRedirection(deviceId, e.endPoint); - } catch (const IoTDBConnectionException& e) { - if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { - deviceIdToEndpoint.erase(deviceId); - try { - defaultSessionConnection_->insertTablet(request); - } - catch (RedirectException& e) { - } - } - else { - throw e; - } - } + auto deviceId = request.prefixPath; + try { + getSessionConnection(deviceId)->insertTablet(request); + } catch (RedirectException& e) { + handleRedirection(deviceId, e.endPoint); + } catch (const IoTDBConnectionException& e) { + if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) != deviceIdToEndpoint.end()) { + deviceIdToEndpoint.erase(deviceId); + try { + defaultSessionConnection_->insertTablet(request); + } catch (RedirectException& e) { + } + } else { + throw e; + } + } } void Session::insertTablet(Tablet& tablet, bool sorted) { - TSInsertTabletReq request; - buildInsertTabletReq(request, tablet, sorted); - insertTablet(request); + TSInsertTabletReq request; + buildInsertTabletReq(request, tablet, sorted); + insertTablet(request); } void Session::insertRelationalTablet(Tablet& tablet, bool sorted) { - std::unordered_map, Tablet> relationalTabletGroup; - if (tableModelDeviceIdToEndpoint.empty()) { - relationalTabletGroup.insert(make_pair(defaultSessionConnection_, tablet)); - } - else if (SessionUtils::isTabletContainsSingleDevice(tablet)) { - relationalTabletGroup.insert(make_pair(getSessionConnection(tablet.getDeviceID(0)), tablet)); - } - else { - for (int row = 0; row < tablet.rowSize; row++) { - auto iDeviceID = tablet.getDeviceID(row); - std::shared_ptr connection = getSessionConnection(iDeviceID); - - auto it = relationalTabletGroup.find(connection); - if (it == relationalTabletGroup.end()) { - Tablet newTablet(tablet.deviceId, tablet.schemas, tablet.columnTypes, tablet.rowSize); - it = relationalTabletGroup.insert(std::make_pair(connection, newTablet)).first; - } - - Tablet& currentTablet = it->second; - int rowIndex = currentTablet.rowSize++; - currentTablet.timestamps[rowIndex] = tablet.timestamps[row]; - for (int col = 0; col < tablet.schemas.size(); col++) { - switch (tablet.schemas[col].second) { - case TSDataType::BOOLEAN: - currentTablet.addValue(tablet.schemas[col].first, rowIndex, - *(bool*)tablet.getValue(col, row, tablet.schemas[col].second)); - break; - case TSDataType::INT32: - currentTablet.addValue(tablet.schemas[col].first, rowIndex, - *(int32_t*)tablet.getValue(col, row, tablet.schemas[col].second)); - break; - case TSDataType::INT64: - case TSDataType::TIMESTAMP: - currentTablet.addValue(tablet.schemas[col].first, rowIndex, - *(int64_t*)tablet.getValue(col, row, tablet.schemas[col].second)); - break; - case TSDataType::FLOAT: - currentTablet.addValue(tablet.schemas[col].first, rowIndex, - *(float*)tablet.getValue(col, row, tablet.schemas[col].second)); - break; - case TSDataType::DOUBLE: - currentTablet.addValue(tablet.schemas[col].first, rowIndex, - *(double*)tablet.getValue(col, row, tablet.schemas[col].second)); - break; - case TSDataType::DATE: { - currentTablet.addValue(tablet.schemas[col].first, rowIndex, - *(boost::gregorian::date*)tablet.getValue(col, row, tablet.schemas[col].second)); - break; - } - case TSDataType::STRING: - case TSDataType::TEXT: - case TSDataType::OBJECT: - case TSDataType::BLOB: { - currentTablet.addValue(tablet.schemas[col].first, rowIndex, - *(string*)tablet.getValue(col, row, tablet.schemas[col].second)); - break; - } - default: - break; - } - - } + std::unordered_map, Tablet> relationalTabletGroup; + if (tableModelDeviceIdToEndpoint.empty()) { + relationalTabletGroup.insert(make_pair(defaultSessionConnection_, tablet)); + } else if (SessionUtils::isTabletContainsSingleDevice(tablet)) { + relationalTabletGroup.insert(make_pair(getSessionConnection(tablet.getDeviceID(0)), tablet)); + } else { + for (int row = 0; row < tablet.rowSize; row++) { + auto iDeviceID = tablet.getDeviceID(row); + std::shared_ptr connection = getSessionConnection(iDeviceID); + + auto it = relationalTabletGroup.find(connection); + if (it == relationalTabletGroup.end()) { + Tablet newTablet(tablet.deviceId, tablet.schemas, tablet.columnTypes, tablet.rowSize); + it = relationalTabletGroup.insert(std::make_pair(connection, newTablet)).first; + } + + Tablet& currentTablet = it->second; + int rowIndex = currentTablet.rowSize++; + currentTablet.timestamps[rowIndex] = tablet.timestamps[row]; + for (int col = 0; col < tablet.schemas.size(); col++) { + switch (tablet.schemas[col].second) { + case TSDataType::BOOLEAN: + currentTablet.addValue(tablet.schemas[col].first, rowIndex, + *(bool*)tablet.getValue(col, row, tablet.schemas[col].second)); + break; + case TSDataType::INT32: + currentTablet.addValue(tablet.schemas[col].first, rowIndex, + *(int32_t*)tablet.getValue(col, row, tablet.schemas[col].second)); + break; + case TSDataType::INT64: + case TSDataType::TIMESTAMP: + currentTablet.addValue(tablet.schemas[col].first, rowIndex, + *(int64_t*)tablet.getValue(col, row, tablet.schemas[col].second)); + break; + case TSDataType::FLOAT: + currentTablet.addValue(tablet.schemas[col].first, rowIndex, + *(float*)tablet.getValue(col, row, tablet.schemas[col].second)); + break; + case TSDataType::DOUBLE: + currentTablet.addValue(tablet.schemas[col].first, rowIndex, + *(double*)tablet.getValue(col, row, tablet.schemas[col].second)); + break; + case TSDataType::DATE: { + currentTablet.addValue( + tablet.schemas[col].first, rowIndex, + *(boost::gregorian::date*)tablet.getValue(col, row, tablet.schemas[col].second)); + break; } + case TSDataType::STRING: + case TSDataType::TEXT: + case TSDataType::OBJECT: + case TSDataType::BLOB: { + currentTablet.addValue(tablet.schemas[col].first, rowIndex, + *(string*)tablet.getValue(col, row, tablet.schemas[col].second)); + break; + } + default: + break; + } + } } - if (relationalTabletGroup.size() == 1) { - insertRelationalTabletOnce(relationalTabletGroup, sorted); - } - else { - insertRelationalTabletByGroup(relationalTabletGroup, sorted); - } + } + if (relationalTabletGroup.size() == 1) { + insertRelationalTabletOnce(relationalTabletGroup, sorted); + } else { + insertRelationalTabletByGroup(relationalTabletGroup, sorted); + } } void Session::insertRelationalTablet(Tablet& tablet) { - insertRelationalTablet(tablet, false); -} - -void Session::insertRelationalTabletOnce(const std::unordered_map, Tablet>& - relationalTabletGroup, bool sorted) { - auto iter = relationalTabletGroup.begin(); + insertRelationalTablet(tablet, false); +} + +void Session::insertRelationalTabletOnce( + const std::unordered_map, Tablet>& relationalTabletGroup, + bool sorted) { + auto iter = relationalTabletGroup.begin(); + auto connection = iter->first; + auto tablet = iter->second; + TSInsertTabletReq request; + buildInsertTabletReq(request, tablet, sorted); + request.__set_writeToTable(true); + std::vector columnCategories; + for (auto& category : tablet.columnTypes) { + columnCategories.push_back(static_cast(category)); + } + request.__set_columnCategories(columnCategories); + try { + TSStatus respStatus; + connection->getSessionClient()->insertTablet(respStatus, request); + RpcUtils::verifySuccess(respStatus); + } catch (RedirectException& e) { + auto endPointList = e.endPointList; + for (int i = 0; i < endPointList.size(); i++) { + auto deviceID = tablet.getDeviceID(i); + handleRedirection(deviceID, endPointList[i]); + } + } catch (const IoTDBConnectionException& e) { + if (endPointToSessionConnection.size() > 1) { + removeBrokenSessionConnection(connection); + try { + TSStatus respStatus; + defaultSessionConnection_->getSessionClient()->insertTablet(respStatus, request); + RpcUtils::verifySuccess(respStatus); + } catch (RedirectException& e) { + } + } else { + throw IoTDBConnectionException(e.what()); + } + } catch (const TTransportException& e) { + log_debug(e.what()); + throw IoTDBConnectionException(e.what()); + } catch (const IoTDBException& e) { + log_debug(e.what()); + throw; + } catch (const exception& e) { + log_debug(e.what()); + throw IoTDBException(e.what()); + } +} + +void Session::insertRelationalTabletByGroup( + const std::unordered_map, Tablet>& relationalTabletGroup, + bool sorted) { + // Create a vector to store future objects for asynchronous operations + std::vector> futures; + + for (auto iter = relationalTabletGroup.begin(); iter != relationalTabletGroup.end(); iter++) { auto connection = iter->first; auto tablet = iter->second; - TSInsertTabletReq request; - buildInsertTabletReq(request, tablet, sorted); - request.__set_writeToTable(true); - std::vector columnCategories; - for (auto& category : tablet.columnTypes) { + + // Launch asynchronous task for each tablet insertion + futures.emplace_back(std::async(std::launch::async, [=]() mutable { + TSInsertTabletReq request; + buildInsertTabletReq(request, tablet, sorted); + request.__set_writeToTable(true); + + std::vector columnCategories; + for (auto& category : tablet.columnTypes) { columnCategories.push_back(static_cast(category)); - } - request.__set_columnCategories(columnCategories); - try { + } + request.__set_columnCategories(columnCategories); + + try { TSStatus respStatus; connection->getSessionClient()->insertTablet(respStatus, request); RpcUtils::verifySuccess(respStatus); - } - catch (RedirectException& e) { - auto endPointList = e.endPointList; - for (int i = 0; i < endPointList.size(); i++) { - auto deviceID = tablet.getDeviceID(i); - handleRedirection(deviceID, endPointList[i]); - } - } catch (const IoTDBConnectionException& e) { - if (endPointToSessionConnection.size() > 1) { - removeBrokenSessionConnection(connection); - try { - TSStatus respStatus; - defaultSessionConnection_->getSessionClient()->insertTablet(respStatus, request); - RpcUtils::verifySuccess(respStatus); - } - catch (RedirectException& e) { - } - } - else { - throw IoTDBConnectionException(e.what()); - } - } catch (const TTransportException& e) { + } catch (const TTransportException& e) { log_debug(e.what()); throw IoTDBConnectionException(e.what()); - } catch (const IoTDBException& e) { + } catch (const IoTDBException& e) { log_debug(e.what()); throw; - } catch (const exception& e) { + } catch (const exception& e) { log_debug(e.what()); throw IoTDBException(e.what()); - } -} - -void Session::insertRelationalTabletByGroup(const std::unordered_map, Tablet>& - relationalTabletGroup, bool sorted) { - // Create a vector to store future objects for asynchronous operations - std::vector> futures; + } + })); + } - for (auto iter = relationalTabletGroup.begin(); iter != relationalTabletGroup.end(); iter++) { - auto connection = iter->first; - auto tablet = iter->second; - - // Launch asynchronous task for each tablet insertion - futures.emplace_back(std::async(std::launch::async, [=]() mutable { - TSInsertTabletReq request; - buildInsertTabletReq(request, tablet, sorted); - request.__set_writeToTable(true); - - std::vector columnCategories; - for (auto& category : tablet.columnTypes) { - columnCategories.push_back(static_cast(category)); - } - request.__set_columnCategories(columnCategories); - - try { - TSStatus respStatus; - connection->getSessionClient()->insertTablet(respStatus, request); - RpcUtils::verifySuccess(respStatus); - } - catch (const TTransportException& e) { - log_debug(e.what()); - throw IoTDBConnectionException(e.what()); - } catch (const IoTDBException& e) { - log_debug(e.what()); - throw; - } catch (const exception& e) { - log_debug(e.what()); - throw IoTDBException(e.what()); - } - })); - } - - for (auto& f : futures) { - f.get(); - } + for (auto& f : futures) { + f.get(); + } } void Session::insertAlignedTablet(Tablet& tablet) { - insertAlignedTablet(tablet, false); + insertAlignedTablet(tablet, false); } void Session::insertAlignedTablet(Tablet& tablet, bool sorted) { - tablet.setAligned(true); - try { - insertTablet(tablet, sorted); - } - catch (const exception& e) { - log_debug(e.what()); - logic_error error(e.what()); - throw exception(error); - } + tablet.setAligned(true); + try { + insertTablet(tablet, sorted); + } catch (const exception& e) { + log_debug(e.what()); + logic_error error(e.what()); + throw exception(error); + } } void Session::insertTablets(unordered_map& tablets) { - try { - insertTablets(tablets, false); - } - catch (const exception& e) { - log_debug(e.what()); - logic_error error(e.what()); - throw exception(error); - } + try { + insertTablets(tablets, false); + } catch (const exception& e) { + log_debug(e.what()); + logic_error error(e.what()); + throw exception(error); + } } void Session::insertTablets(unordered_map& tablets, bool sorted) { - if (tablets.empty()) { - throw BatchExecutionException("No tablet is inserting!"); - } - auto beginIter = tablets.begin(); - bool isAligned = ((*beginIter).second)->isAligned; - if (enableRedirection_) { - insertTabletsWithLeaderCache(tablets, sorted, isAligned); - } - else { - TSInsertTabletsReq request; - for (const auto& item : tablets) { - if (isAligned != item.second->isAligned) { - throw BatchExecutionException("The tablets should be all aligned or non-aligned!"); - } - if (!checkSorted(*(item.second))) { - sortTablet(*(item.second)); - } - request.prefixPaths.push_back(item.second->deviceId); - vector measurements; - vector dataTypes; - for (pair schema : item.second->schemas) { - measurements.push_back(schema.first); - dataTypes.push_back(schema.second); - } - request.measurementsList.push_back(measurements); - request.typesList.push_back(dataTypes); - request.timestampsList.push_back(move(SessionUtils::getTime(*(item.second)))); - request.valuesList.push_back(move(SessionUtils::getValue(*(item.second)))); - request.sizeList.push_back(item.second->rowSize); - } - request.__set_isAligned(isAligned); - try { - TSStatus respStatus; - defaultSessionConnection_->insertTablets(request); - RpcUtils::verifySuccess(respStatus); - } - catch (RedirectException& e) { - } - } -} - - -void Session::insertAlignedTablets(unordered_map& tablets, bool sorted) { - for (auto iter = tablets.begin(); iter != tablets.end(); iter++) { - iter->second->setAligned(true); - } + if (tablets.empty()) { + throw BatchExecutionException("No tablet is inserting!"); + } + auto beginIter = tablets.begin(); + bool isAligned = ((*beginIter).second)->isAligned; + if (enableRedirection_) { + insertTabletsWithLeaderCache(tablets, sorted, isAligned); + } else { + TSInsertTabletsReq request; + for (const auto& item : tablets) { + if (isAligned != item.second->isAligned) { + throw BatchExecutionException("The tablets should be all aligned or non-aligned!"); + } + if (!checkSorted(*(item.second))) { + sortTablet(*(item.second)); + } + request.prefixPaths.push_back(item.second->deviceId); + vector measurements; + vector dataTypes; + for (pair schema : item.second->schemas) { + measurements.push_back(schema.first); + dataTypes.push_back(schema.second); + } + request.measurementsList.push_back(measurements); + request.typesList.push_back(dataTypes); + request.timestampsList.push_back(move(SessionUtils::getTime(*(item.second)))); + request.valuesList.push_back(move(SessionUtils::getValue(*(item.second)))); + request.sizeList.push_back(item.second->rowSize); + } + request.__set_isAligned(isAligned); try { - insertTablets(tablets, sorted); - } - catch (const exception& e) { - log_debug(e.what()); - logic_error error(e.what()); - throw exception(error); + TSStatus respStatus; + defaultSessionConnection_->insertTablets(request); + RpcUtils::verifySuccess(respStatus); + } catch (RedirectException& e) { } + } } -void Session::testInsertRecord(const string& deviceId, int64_t time, const vector& measurements, - const vector& values) { - TSInsertStringRecordReq req; - req.__set_prefixPath(deviceId); - req.__set_timestamp(time); - req.__set_measurements(measurements); - req.__set_values(values); - TSStatus tsStatus; - try { - defaultSessionConnection_->testInsertStringRecord(req); - RpcUtils::verifySuccess(tsStatus); - } - catch (const TTransportException& e) { - log_debug(e.what()); - throw IoTDBConnectionException(e.what()); - } catch (const IoTDBException& e) { - log_debug(e.what()); - throw; - } catch (const exception& e) { - log_debug(e.what()); - throw IoTDBException(e.what()); - } +void Session::insertAlignedTablets(unordered_map& tablets, bool sorted) { + for (auto iter = tablets.begin(); iter != tablets.end(); iter++) { + iter->second->setAligned(true); + } + try { + insertTablets(tablets, sorted); + } catch (const exception& e) { + log_debug(e.what()); + logic_error error(e.what()); + throw exception(error); + } +} + +void Session::testInsertRecord(const string& deviceId, int64_t time, + const vector& measurements, const vector& values) { + TSInsertStringRecordReq req; + req.__set_prefixPath(deviceId); + req.__set_timestamp(time); + req.__set_measurements(measurements); + req.__set_values(values); + TSStatus tsStatus; + try { + defaultSessionConnection_->testInsertStringRecord(req); + RpcUtils::verifySuccess(tsStatus); + } catch (const TTransportException& e) { + log_debug(e.what()); + throw IoTDBConnectionException(e.what()); + } catch (const IoTDBException& e) { + log_debug(e.what()); + throw; + } catch (const exception& e) { + log_debug(e.what()); + throw IoTDBException(e.what()); + } } void Session::testInsertTablet(const Tablet& tablet) { - TSInsertTabletReq request; - request.prefixPath = tablet.deviceId; - for (pair schema : tablet.schemas) { - request.measurements.push_back(schema.first); - request.types.push_back(schema.second); - } - request.__set_timestamps(move(SessionUtils::getTime(tablet))); - request.__set_values(move(SessionUtils::getValue(tablet))); - request.__set_size(tablet.rowSize); - try { - TSStatus tsStatus; - defaultSessionConnection_->testInsertTablet(request); - RpcUtils::verifySuccess(tsStatus); - } - catch (const TTransportException& e) { - log_debug(e.what()); - throw IoTDBConnectionException(e.what()); - } catch (const IoTDBException& e) { - log_debug(e.what()); - throw; - } catch (const exception& e) { - log_debug(e.what()); - throw IoTDBException(e.what()); - } -} - -void Session::testInsertRecords(const vector& deviceIds, - const vector& times, + TSInsertTabletReq request; + request.prefixPath = tablet.deviceId; + for (pair schema : tablet.schemas) { + request.measurements.push_back(schema.first); + request.types.push_back(schema.second); + } + request.__set_timestamps(move(SessionUtils::getTime(tablet))); + request.__set_values(move(SessionUtils::getValue(tablet))); + request.__set_size(tablet.rowSize); + try { + TSStatus tsStatus; + defaultSessionConnection_->testInsertTablet(request); + RpcUtils::verifySuccess(tsStatus); + } catch (const TTransportException& e) { + log_debug(e.what()); + throw IoTDBConnectionException(e.what()); + } catch (const IoTDBException& e) { + log_debug(e.what()); + throw; + } catch (const exception& e) { + log_debug(e.what()); + throw IoTDBException(e.what()); + } +} + +void Session::testInsertRecords(const vector& deviceIds, const vector& times, const vector>& measurementsList, const vector>& valuesList) { - size_t len = deviceIds.size(); - if (len != times.size() || len != measurementsList.size() || len != valuesList.size()) { - logic_error error("deviceIds, times, measurementsList and valuesList's size should be equal"); - throw exception(error); - } - TSInsertStringRecordsReq request; - request.__set_prefixPaths(deviceIds); - request.__set_timestamps(times); - request.__set_measurementsList(measurementsList); - request.__set_valuesList(valuesList); - - try { - TSStatus tsStatus; - defaultSessionConnection_->getSessionClient()->insertStringRecords(tsStatus, request); - RpcUtils::verifySuccess(tsStatus); - } - catch (const TTransportException& e) { - log_debug(e.what()); - throw IoTDBConnectionException(e.what()); - } catch (const IoTDBException& e) { - log_debug(e.what()); - throw; - } catch (const exception& e) { - log_debug(e.what()); - throw IoTDBException(e.what()); - } + size_t len = deviceIds.size(); + if (len != times.size() || len != measurementsList.size() || len != valuesList.size()) { + logic_error error("deviceIds, times, measurementsList and valuesList's size should be equal"); + throw exception(error); + } + TSInsertStringRecordsReq request; + request.__set_prefixPaths(deviceIds); + request.__set_timestamps(times); + request.__set_measurementsList(measurementsList); + request.__set_valuesList(valuesList); + + try { + TSStatus tsStatus; + defaultSessionConnection_->getSessionClient()->insertStringRecords(tsStatus, request); + RpcUtils::verifySuccess(tsStatus); + } catch (const TTransportException& e) { + log_debug(e.what()); + throw IoTDBConnectionException(e.what()); + } catch (const IoTDBException& e) { + log_debug(e.what()); + throw; + } catch (const exception& e) { + log_debug(e.what()); + throw IoTDBException(e.what()); + } } void Session::deleteTimeseries(const string& path) { - vector paths; - paths.push_back(path); - deleteTimeseries(paths); + vector paths; + paths.push_back(path); + deleteTimeseries(paths); } void Session::deleteTimeseries(const vector& paths) { - defaultSessionConnection_->deleteTimeseries(paths); + defaultSessionConnection_->deleteTimeseries(paths); } void Session::deleteData(const string& path, int64_t endTime) { - vector paths; - paths.push_back(path); - deleteData(paths, LONG_LONG_MIN, endTime); + vector paths; + paths.push_back(path); + deleteData(paths, LONG_LONG_MIN, endTime); } void Session::deleteData(const vector& paths, int64_t endTime) { - deleteData(paths, LONG_LONG_MIN, endTime); + deleteData(paths, LONG_LONG_MIN, endTime); } void Session::deleteData(const vector& paths, int64_t startTime, int64_t endTime) { - TSDeleteDataReq req; - req.__set_paths(paths); - req.__set_startTime(startTime); - req.__set_endTime(endTime); - defaultSessionConnection_->deleteData(req); + TSDeleteDataReq req; + req.__set_paths(paths); + req.__set_startTime(startTime); + req.__set_endTime(endTime); + defaultSessionConnection_->deleteData(req); } void Session::setStorageGroup(const string& storageGroupId) { - defaultSessionConnection_->setStorageGroup(storageGroupId); + defaultSessionConnection_->setStorageGroup(storageGroupId); } void Session::deleteStorageGroup(const string& storageGroup) { - vector storageGroups; - storageGroups.push_back(storageGroup); - deleteStorageGroups(storageGroups); + vector storageGroups; + storageGroups.push_back(storageGroup); + deleteStorageGroups(storageGroups); } void Session::deleteStorageGroups(const vector& storageGroups) { - defaultSessionConnection_->deleteStorageGroups(storageGroups); + defaultSessionConnection_->deleteStorageGroups(storageGroups); } void Session::createDatabase(const string& database) { - this->setStorageGroup(database); + this->setStorageGroup(database); } void Session::deleteDatabase(const string& database) { - this->deleteStorageGroups(vector{database}); + this->deleteStorageGroups(vector{database}); } void Session::deleteDatabases(const vector& databases) { - this->deleteStorageGroups(databases); + this->deleteStorageGroups(databases); } -void Session::createTimeseries(const string& path, - TSDataType::TSDataType dataType, +void Session::createTimeseries(const string& path, TSDataType::TSDataType dataType, TSEncoding::TSEncoding encoding, CompressionType::CompressionType compressor) { - try { - createTimeseries(path, dataType, encoding, compressor, nullptr, nullptr, nullptr, ""); - } - catch (const exception& e) { - log_debug(e.what()); - throw IoTDBException(e.what()); - } + try { + createTimeseries(path, dataType, encoding, compressor, nullptr, nullptr, nullptr, ""); + } catch (const exception& e) { + log_debug(e.what()); + throw IoTDBException(e.what()); + } } -void Session::createTimeseries(const string& path, - TSDataType::TSDataType dataType, +void Session::createTimeseries(const string& path, TSDataType::TSDataType dataType, TSEncoding::TSEncoding encoding, CompressionType::CompressionType compressor, - map* props, - map* tags, - map* attributes, - const string& measurementAlias) { - TSCreateTimeseriesReq req; - req.__set_path(path); - req.__set_dataType(dataType); - req.__set_encoding(encoding); - req.__set_compressor(compressor); - if (props != nullptr) { - req.__set_props(*props); - } - - if (tags != nullptr) { - req.__set_tags(*tags); - } - if (attributes != nullptr) { - req.__set_attributes(*attributes); - } - if (!measurementAlias.empty()) { - req.__set_measurementAlias(measurementAlias); - } - defaultSessionConnection_->createTimeseries(req); + map* props, map* tags, + map* attributes, const string& measurementAlias) { + TSCreateTimeseriesReq req; + req.__set_path(path); + req.__set_dataType(dataType); + req.__set_encoding(encoding); + req.__set_compressor(compressor); + if (props != nullptr) { + req.__set_props(*props); + } + + if (tags != nullptr) { + req.__set_tags(*tags); + } + if (attributes != nullptr) { + req.__set_attributes(*attributes); + } + if (!measurementAlias.empty()) { + req.__set_measurementAlias(measurementAlias); + } + defaultSessionConnection_->createTimeseries(req); } void Session::createMultiTimeseries(const vector& paths, @@ -1851,444 +1776,453 @@ void Session::createMultiTimeseries(const vector& paths, vector>* tagsList, vector>* attributesList, vector* measurementAliasList) { - TSCreateMultiTimeseriesReq request; - request.__set_paths(paths); - - vector dataTypesOrdinal; - dataTypesOrdinal.reserve(dataTypes.size()); - for (TSDataType::TSDataType dataType : dataTypes) { - dataTypesOrdinal.push_back(dataType); - } - request.__set_dataTypes(dataTypesOrdinal); - - vector encodingsOrdinal; - encodingsOrdinal.reserve(encodings.size()); - for (TSEncoding::TSEncoding encoding : encodings) { - encodingsOrdinal.push_back(encoding); - } - request.__set_encodings(encodingsOrdinal); - - vector compressorsOrdinal; - compressorsOrdinal.reserve(compressors.size()); - for (CompressionType::CompressionType compressor : compressors) { - compressorsOrdinal.push_back(compressor); - } - request.__set_compressors(compressorsOrdinal); - - if (propsList != nullptr) { - request.__set_propsList(*propsList); - } - - if (tagsList != nullptr) { - request.__set_tagsList(*tagsList); - } - if (attributesList != nullptr) { - request.__set_attributesList(*attributesList); - } - if (measurementAliasList != nullptr) { - request.__set_measurementAliasList(*measurementAliasList); - } - - defaultSessionConnection_->createMultiTimeseries(request); -} - -void Session::createAlignedTimeseries(const std::string& deviceId, - const std::vector& measurements, - const std::vector& dataTypes, - const std::vector& encodings, - const std::vector& compressors) { - TSCreateAlignedTimeseriesReq request; - request.__set_prefixPath(deviceId); - request.__set_measurements(measurements); - - vector dataTypesOrdinal; - dataTypesOrdinal.reserve(dataTypes.size()); - for (TSDataType::TSDataType dataType : dataTypes) { - dataTypesOrdinal.push_back(dataType); - } - request.__set_dataTypes(dataTypesOrdinal); - - vector encodingsOrdinal; - encodingsOrdinal.reserve(encodings.size()); - for (TSEncoding::TSEncoding encoding : encodings) { - encodingsOrdinal.push_back(encoding); - } - request.__set_encodings(encodingsOrdinal); - - vector compressorsOrdinal; - compressorsOrdinal.reserve(compressors.size()); - for (CompressionType::CompressionType compressor : compressors) { - compressorsOrdinal.push_back(compressor); - } - request.__set_compressors(compressorsOrdinal); - - defaultSessionConnection_->createAlignedTimeseries(request); + TSCreateMultiTimeseriesReq request; + request.__set_paths(paths); + + vector dataTypesOrdinal; + dataTypesOrdinal.reserve(dataTypes.size()); + for (TSDataType::TSDataType dataType : dataTypes) { + dataTypesOrdinal.push_back(dataType); + } + request.__set_dataTypes(dataTypesOrdinal); + + vector encodingsOrdinal; + encodingsOrdinal.reserve(encodings.size()); + for (TSEncoding::TSEncoding encoding : encodings) { + encodingsOrdinal.push_back(encoding); + } + request.__set_encodings(encodingsOrdinal); + + vector compressorsOrdinal; + compressorsOrdinal.reserve(compressors.size()); + for (CompressionType::CompressionType compressor : compressors) { + compressorsOrdinal.push_back(compressor); + } + request.__set_compressors(compressorsOrdinal); + + if (propsList != nullptr) { + request.__set_propsList(*propsList); + } + + if (tagsList != nullptr) { + request.__set_tagsList(*tagsList); + } + if (attributesList != nullptr) { + request.__set_attributesList(*attributesList); + } + if (measurementAliasList != nullptr) { + request.__set_measurementAliasList(*measurementAliasList); + } + + defaultSessionConnection_->createMultiTimeseries(request); +} + +void Session::createAlignedTimeseries( + const std::string& deviceId, const std::vector& measurements, + const std::vector& dataTypes, + const std::vector& encodings, + const std::vector& compressors) { + TSCreateAlignedTimeseriesReq request; + request.__set_prefixPath(deviceId); + request.__set_measurements(measurements); + + vector dataTypesOrdinal; + dataTypesOrdinal.reserve(dataTypes.size()); + for (TSDataType::TSDataType dataType : dataTypes) { + dataTypesOrdinal.push_back(dataType); + } + request.__set_dataTypes(dataTypesOrdinal); + + vector encodingsOrdinal; + encodingsOrdinal.reserve(encodings.size()); + for (TSEncoding::TSEncoding encoding : encodings) { + encodingsOrdinal.push_back(encoding); + } + request.__set_encodings(encodingsOrdinal); + + vector compressorsOrdinal; + compressorsOrdinal.reserve(compressors.size()); + for (CompressionType::CompressionType compressor : compressors) { + compressorsOrdinal.push_back(compressor); + } + request.__set_compressors(compressorsOrdinal); + + defaultSessionConnection_->createAlignedTimeseries(request); } bool Session::checkTimeseriesExists(const string& path) { - try { - std::unique_ptr dataset = executeQueryStatement("SHOW TIMESERIES " + path); - if (dataset == nullptr) { - throw IoTDBException("executeQueryStatement failed"); - } - bool isExisted = dataset->hasNext(); - dataset->closeOperationHandle(); - return isExisted; - } - catch (const exception& e) { - log_debug(e.what()); - throw IoTDBException(e.what()); + try { + std::unique_ptr dataset = executeQueryStatement("SHOW TIMESERIES " + path); + if (dataset == nullptr) { + throw IoTDBException("executeQueryStatement failed"); } + bool isExisted = dataset->hasNext(); + dataset->closeOperationHandle(); + return isExisted; + } catch (const exception& e) { + log_debug(e.what()); + throw IoTDBException(e.what()); + } } shared_ptr Session::getQuerySessionConnection() { - auto endPoint = nodesSupplier_->getQueryEndPoint(); - if (!endPoint.is_initialized() || endPointToSessionConnection.empty()) { - return defaultSessionConnection_; - } - - auto it = endPointToSessionConnection.find(endPoint.value()); - if (it != endPointToSessionConnection.end()) { - return it->second; - } - - shared_ptr newConnection; - try { - newConnection = make_shared(this, endPoint.value(), zoneId_, nodesSupplier_, - fetchSize_, 60, 500, connectTimeoutMs_, sqlDialect_, database_); - endPointToSessionConnection.emplace(endPoint.value(), newConnection); - return newConnection; - } - catch (exception& e) { - log_debug("Session::getQuerySessionConnection() exception: " + e.what()); - return newConnection; - } + auto endPoint = nodesSupplier_->getQueryEndPoint(); + if (!endPoint.is_initialized() || endPointToSessionConnection.empty()) { + return defaultSessionConnection_; + } + + auto it = endPointToSessionConnection.find(endPoint.value()); + if (it != endPointToSessionConnection.end()) { + return it->second; + } + + shared_ptr newConnection; + try { + newConnection = + make_shared(this, endPoint.value(), zoneId_, nodesSupplier_, fetchSize_, + 60, 500, connectTimeoutMs_, sqlDialect_, database_); + endPointToSessionConnection.emplace(endPoint.value(), newConnection); + return newConnection; + } catch (exception& e) { + log_debug("Session::getQuerySessionConnection() exception: " + e.what()); + return newConnection; + } } shared_ptr Session::getSessionConnection(std::string deviceId) { - if (!enableRedirection_ || - deviceIdToEndpoint.find(deviceId) == deviceIdToEndpoint.end() || - endPointToSessionConnection.find(deviceIdToEndpoint[deviceId]) == endPointToSessionConnection.end()) { - return defaultSessionConnection_; - } - return endPointToSessionConnection.find(deviceIdToEndpoint[deviceId])->second; + if (!enableRedirection_ || deviceIdToEndpoint.find(deviceId) == deviceIdToEndpoint.end() || + endPointToSessionConnection.find(deviceIdToEndpoint[deviceId]) == + endPointToSessionConnection.end()) { + return defaultSessionConnection_; + } + return endPointToSessionConnection.find(deviceIdToEndpoint[deviceId])->second; } -shared_ptr Session::getSessionConnection(std::shared_ptr deviceId) { - if (!enableRedirection_ || - tableModelDeviceIdToEndpoint.find(deviceId) == tableModelDeviceIdToEndpoint.end() || - endPointToSessionConnection.find(tableModelDeviceIdToEndpoint[deviceId]) == endPointToSessionConnection.end()) { - return defaultSessionConnection_; - } - return endPointToSessionConnection.find(tableModelDeviceIdToEndpoint[deviceId])->second; +shared_ptr +Session::getSessionConnection(std::shared_ptr deviceId) { + if (!enableRedirection_ || + tableModelDeviceIdToEndpoint.find(deviceId) == tableModelDeviceIdToEndpoint.end() || + endPointToSessionConnection.find(tableModelDeviceIdToEndpoint[deviceId]) == + endPointToSessionConnection.end()) { + return defaultSessionConnection_; + } + return endPointToSessionConnection.find(tableModelDeviceIdToEndpoint[deviceId])->second; } string Session::getTimeZone() { - auto ret = defaultSessionConnection_->getTimeZone(); - return ret.timeZone; + auto ret = defaultSessionConnection_->getTimeZone(); + return ret.timeZone; } void Session::setTimeZone(const string& zoneId) { - TSSetTimeZoneReq req; - req.__set_sessionId(defaultSessionConnection_->sessionId); - req.__set_timeZone(zoneId); - defaultSessionConnection_->setTimeZone(req); + TSSetTimeZoneReq req; + req.__set_sessionId(defaultSessionConnection_->sessionId); + req.__set_timeZone(zoneId); + defaultSessionConnection_->setTimeZone(req); } unique_ptr Session::executeQueryStatement(const string& sql) { - return executeQueryStatementMayRedirect(sql, QUERY_TIMEOUT_MS); + return executeQueryStatementMayRedirect(sql, QUERY_TIMEOUT_MS); } unique_ptr Session::executeQueryStatement(const string& sql, int64_t timeoutInMs) { - return executeQueryStatementMayRedirect(sql, timeoutInMs); + return executeQueryStatementMayRedirect(sql, timeoutInMs); } void Session::handleQueryRedirection(TEndPoint endPoint) { - if (!enableRedirection_) return; - shared_ptr newConnection; - auto it = endPointToSessionConnection.find(endPoint); - if (it != endPointToSessionConnection.end()) { - newConnection = it->second; - } - else { - try { - newConnection = make_shared(this, endPoint, zoneId_, nodesSupplier_, - fetchSize_, 60, 500, connectTimeoutMs_, sqlDialect_, database_); - - endPointToSessionConnection.emplace(endPoint, newConnection); - } - catch (exception& e) { - throw IoTDBConnectionException(e.what()); - } + if (!enableRedirection_) + return; + shared_ptr newConnection; + auto it = endPointToSessionConnection.find(endPoint); + if (it != endPointToSessionConnection.end()) { + newConnection = it->second; + } else { + try { + newConnection = + make_shared(this, endPoint, zoneId_, nodesSupplier_, fetchSize_, 60, + 500, connectTimeoutMs_, sqlDialect_, database_); + + endPointToSessionConnection.emplace(endPoint, newConnection); + } catch (exception& e) { + throw IoTDBConnectionException(e.what()); } - defaultSessionConnection_ = newConnection; + } + defaultSessionConnection_ = newConnection; } void Session::handleRedirection(const std::string& deviceId, TEndPoint endPoint) { - if (!enableRedirection_) return; - if (endPoint.ip == "127.0.0.1") return; - deviceIdToEndpoint[deviceId] = endPoint; - - shared_ptr newConnection; - auto it = endPointToSessionConnection.find(endPoint); - if (it != endPointToSessionConnection.end()) { - newConnection = it->second; - } - else { - try { - newConnection = make_shared(this, endPoint, zoneId_, nodesSupplier_, - fetchSize_, 60, 500, 1000, sqlDialect_, database_); - endPointToSessionConnection.emplace(endPoint, newConnection); - } - catch (exception& e) { - deviceIdToEndpoint.erase(deviceId); - throw IoTDBConnectionException(e.what()); - } + if (!enableRedirection_) + return; + if (endPoint.ip == "127.0.0.1") + return; + deviceIdToEndpoint[deviceId] = endPoint; + + shared_ptr newConnection; + auto it = endPointToSessionConnection.find(endPoint); + if (it != endPointToSessionConnection.end()) { + newConnection = it->second; + } else { + try { + newConnection = + make_shared(this, endPoint, zoneId_, nodesSupplier_, fetchSize_, 60, + 500, 1000, sqlDialect_, database_); + endPointToSessionConnection.emplace(endPoint, newConnection); + } catch (exception& e) { + deviceIdToEndpoint.erase(deviceId); + throw IoTDBConnectionException(e.what()); } + } } -void Session::handleRedirection(const std::shared_ptr& deviceId, TEndPoint endPoint) { - if (!enableRedirection_) return; - if (endPoint.ip == "127.0.0.1") return; - tableModelDeviceIdToEndpoint[deviceId] = endPoint; - - shared_ptr newConnection; - auto it = endPointToSessionConnection.find(endPoint); - if (it != endPointToSessionConnection.end()) { - newConnection = it->second; - } - else { - try { - newConnection = make_shared(this, endPoint, zoneId_, nodesSupplier_, - fetchSize_, 3, 500, connectTimeoutMs_, sqlDialect_, database_); - endPointToSessionConnection.emplace(endPoint, newConnection); - } - catch (exception& e) { - tableModelDeviceIdToEndpoint.erase(deviceId); - throw IoTDBConnectionException(e.what()); - } - } -} +void Session::handleRedirection(const std::shared_ptr& deviceId, + TEndPoint endPoint) { + if (!enableRedirection_) + return; + if (endPoint.ip == "127.0.0.1") + return; + tableModelDeviceIdToEndpoint[deviceId] = endPoint; -std::unique_ptr Session::executeQueryStatementMayRedirect(const std::string& sql, int64_t timeoutInMs) { - auto sessionConnection = getQuerySessionConnection(); - if (!sessionConnection) { - log_warn("Session connection not found"); - return nullptr; - } + shared_ptr newConnection; + auto it = endPointToSessionConnection.find(endPoint); + if (it != endPointToSessionConnection.end()) { + newConnection = it->second; + } else { try { - return sessionConnection->executeQueryStatement(sql, timeoutInMs); - } - catch (RedirectException& e) { - log_warn("Session connection redirect exception: " + e.what()); - handleQueryRedirection(e.endPoint); - try { - return defaultSessionConnection_->executeQueryStatement(sql, timeoutInMs); - } - catch (exception& e) { - log_error("Exception while executing redirected query statement: %s", e.what()); - throw ExecutionException(e.what()); - } + newConnection = + make_shared(this, endPoint, zoneId_, nodesSupplier_, fetchSize_, 3, + 500, connectTimeoutMs_, sqlDialect_, database_); + endPointToSessionConnection.emplace(endPoint, newConnection); + } catch (exception& e) { + tableModelDeviceIdToEndpoint.erase(deviceId); + throw IoTDBConnectionException(e.what()); + } + } +} + +std::unique_ptr Session::executeQueryStatementMayRedirect(const std::string& sql, + int64_t timeoutInMs) { + auto sessionConnection = getQuerySessionConnection(); + if (!sessionConnection) { + log_warn("Session connection not found"); + return nullptr; + } + try { + return sessionConnection->executeQueryStatement(sql, timeoutInMs); + } catch (RedirectException& e) { + log_warn("Session connection redirect exception: " + e.what()); + handleQueryRedirection(e.endPoint); + try { + return defaultSessionConnection_->executeQueryStatement(sql, timeoutInMs); } catch (exception& e) { - log_error("Exception while executing query statement: %s", e.what()); - throw e; + log_error("Exception while executing redirected query statement: %s", e.what()); + throw ExecutionException(e.what()); } + } catch (exception& e) { + log_error("Exception while executing query statement: %s", e.what()); + throw e; + } } void Session::executeNonQueryStatement(const string& sql) { - try { - defaultSessionConnection_->executeNonQueryStatement(sql); - } - catch (const exception& e) { - throw IoTDBException(e.what()); - } + try { + defaultSessionConnection_->executeNonQueryStatement(sql); + } catch (const exception& e) { + throw IoTDBException(e.what()); + } } -unique_ptr -Session::executeRawDataQuery(const vector& paths, int64_t startTime, int64_t endTime) { - return defaultSessionConnection_->executeRawDataQuery(paths, startTime, endTime); +unique_ptr Session::executeRawDataQuery(const vector& paths, + int64_t startTime, int64_t endTime) { + return defaultSessionConnection_->executeRawDataQuery(paths, startTime, endTime); } - unique_ptr Session::executeLastDataQuery(const vector& paths) { - return executeLastDataQuery(paths, LONG_LONG_MIN); + return executeLastDataQuery(paths, LONG_LONG_MIN); } -unique_ptr Session::executeLastDataQuery(const vector& paths, int64_t lastTime) { - return defaultSessionConnection_->executeLastDataQuery(paths, lastTime); +unique_ptr Session::executeLastDataQuery(const vector& paths, + int64_t lastTime) { + return defaultSessionConnection_->executeLastDataQuery(paths, lastTime); } void Session::createSchemaTemplate(const Template& templ) { - TSCreateSchemaTemplateReq req; - req.__set_name(templ.getName()); - req.__set_serializedTemplate(templ.serialize()); - defaultSessionConnection_->createSchemaTemplate(req); + TSCreateSchemaTemplateReq req; + req.__set_name(templ.getName()); + req.__set_serializedTemplate(templ.serialize()); + defaultSessionConnection_->createSchemaTemplate(req); } void Session::setSchemaTemplate(const string& template_name, const string& prefix_path) { - TSSetSchemaTemplateReq req; - req.__set_templateName(template_name); - req.__set_prefixPath(prefix_path); - defaultSessionConnection_->setSchemaTemplate(req); + TSSetSchemaTemplateReq req; + req.__set_templateName(template_name); + req.__set_prefixPath(prefix_path); + defaultSessionConnection_->setSchemaTemplate(req); } void Session::unsetSchemaTemplate(const string& prefix_path, const string& template_name) { - TSUnsetSchemaTemplateReq req; - req.__set_templateName(template_name); - req.__set_prefixPath(prefix_path); - defaultSessionConnection_->unsetSchemaTemplate(req); -} - -void Session::addAlignedMeasurementsInTemplate(const string& template_name, const vector& measurements, - const vector& dataTypes, - const vector& encodings, - const vector& compressors) { - TSAppendSchemaTemplateReq req; - req.__set_name(template_name); - req.__set_measurements(measurements); - req.__set_isAligned(true); - - vector dataTypesOrdinal; - dataTypesOrdinal.reserve(dataTypes.size()); - for (TSDataType::TSDataType dataType : dataTypes) { - dataTypesOrdinal.push_back(dataType); - } - req.__set_dataTypes(dataTypesOrdinal); - - vector encodingsOrdinal; - encodingsOrdinal.reserve(encodings.size()); - for (TSEncoding::TSEncoding encoding : encodings) { - encodingsOrdinal.push_back(encoding); - } - req.__set_encodings(encodingsOrdinal); - - vector compressorsOrdinal; - compressorsOrdinal.reserve(compressors.size()); - for (CompressionType::CompressionType compressor : compressors) { - compressorsOrdinal.push_back(compressor); - } - req.__set_compressors(compressorsOrdinal); - - defaultSessionConnection_->appendSchemaTemplate(req); -} - -void Session::addAlignedMeasurementsInTemplate(const string& template_name, const string& measurement, - TSDataType::TSDataType dataType, TSEncoding::TSEncoding encoding, + TSUnsetSchemaTemplateReq req; + req.__set_templateName(template_name); + req.__set_prefixPath(prefix_path); + defaultSessionConnection_->unsetSchemaTemplate(req); +} + +void Session::addAlignedMeasurementsInTemplate( + const string& template_name, const vector& measurements, + const vector& dataTypes, + const vector& encodings, + const vector& compressors) { + TSAppendSchemaTemplateReq req; + req.__set_name(template_name); + req.__set_measurements(measurements); + req.__set_isAligned(true); + + vector dataTypesOrdinal; + dataTypesOrdinal.reserve(dataTypes.size()); + for (TSDataType::TSDataType dataType : dataTypes) { + dataTypesOrdinal.push_back(dataType); + } + req.__set_dataTypes(dataTypesOrdinal); + + vector encodingsOrdinal; + encodingsOrdinal.reserve(encodings.size()); + for (TSEncoding::TSEncoding encoding : encodings) { + encodingsOrdinal.push_back(encoding); + } + req.__set_encodings(encodingsOrdinal); + + vector compressorsOrdinal; + compressorsOrdinal.reserve(compressors.size()); + for (CompressionType::CompressionType compressor : compressors) { + compressorsOrdinal.push_back(compressor); + } + req.__set_compressors(compressorsOrdinal); + + defaultSessionConnection_->appendSchemaTemplate(req); +} + +void Session::addAlignedMeasurementsInTemplate(const string& template_name, + const string& measurement, + TSDataType::TSDataType dataType, + TSEncoding::TSEncoding encoding, CompressionType::CompressionType compressor) { - vector measurements(1, measurement); - vector dataTypes(1, dataType); - vector encodings(1, encoding); - vector compressors(1, compressor); - addAlignedMeasurementsInTemplate(template_name, measurements, dataTypes, encodings, compressors); -} - -void Session::addUnalignedMeasurementsInTemplate(const string& template_name, const vector& measurements, - const vector& dataTypes, - const vector& encodings, - const vector& compressors) { - TSAppendSchemaTemplateReq req; - req.__set_name(template_name); - req.__set_measurements(measurements); - req.__set_isAligned(false); - - vector dataTypesOrdinal; - dataTypesOrdinal.reserve(dataTypes.size()); - for (TSDataType::TSDataType dataType : dataTypes) { - dataTypesOrdinal.push_back(dataType); - } - req.__set_dataTypes(dataTypesOrdinal); - - vector encodingsOrdinal; - encodingsOrdinal.reserve(encodings.size()); - for (TSEncoding::TSEncoding encoding : encodings) { - encodingsOrdinal.push_back(encoding); - } - req.__set_encodings(encodingsOrdinal); - - vector compressorsOrdinal; - compressorsOrdinal.reserve(compressors.size()); - for (CompressionType::CompressionType compressor : compressors) { - compressorsOrdinal.push_back(compressor); - } - req.__set_compressors(compressorsOrdinal); - - defaultSessionConnection_->appendSchemaTemplate(req); -} - -void Session::addUnalignedMeasurementsInTemplate(const string& template_name, const string& measurement, - TSDataType::TSDataType dataType, TSEncoding::TSEncoding encoding, + vector measurements(1, measurement); + vector dataTypes(1, dataType); + vector encodings(1, encoding); + vector compressors(1, compressor); + addAlignedMeasurementsInTemplate(template_name, measurements, dataTypes, encodings, compressors); +} + +void Session::addUnalignedMeasurementsInTemplate( + const string& template_name, const vector& measurements, + const vector& dataTypes, + const vector& encodings, + const vector& compressors) { + TSAppendSchemaTemplateReq req; + req.__set_name(template_name); + req.__set_measurements(measurements); + req.__set_isAligned(false); + + vector dataTypesOrdinal; + dataTypesOrdinal.reserve(dataTypes.size()); + for (TSDataType::TSDataType dataType : dataTypes) { + dataTypesOrdinal.push_back(dataType); + } + req.__set_dataTypes(dataTypesOrdinal); + + vector encodingsOrdinal; + encodingsOrdinal.reserve(encodings.size()); + for (TSEncoding::TSEncoding encoding : encodings) { + encodingsOrdinal.push_back(encoding); + } + req.__set_encodings(encodingsOrdinal); + + vector compressorsOrdinal; + compressorsOrdinal.reserve(compressors.size()); + for (CompressionType::CompressionType compressor : compressors) { + compressorsOrdinal.push_back(compressor); + } + req.__set_compressors(compressorsOrdinal); + + defaultSessionConnection_->appendSchemaTemplate(req); +} + +void Session::addUnalignedMeasurementsInTemplate(const string& template_name, + const string& measurement, + TSDataType::TSDataType dataType, + TSEncoding::TSEncoding encoding, CompressionType::CompressionType compressor) { - vector measurements(1, measurement); - vector dataTypes(1, dataType); - vector encodings(1, encoding); - vector compressors(1, compressor); - addUnalignedMeasurementsInTemplate(template_name, measurements, dataTypes, encodings, compressors); + vector measurements(1, measurement); + vector dataTypes(1, dataType); + vector encodings(1, encoding); + vector compressors(1, compressor); + addUnalignedMeasurementsInTemplate(template_name, measurements, dataTypes, encodings, + compressors); } void Session::deleteNodeInTemplate(const string& template_name, const string& path) { - TSPruneSchemaTemplateReq req; - req.__set_name(template_name); - req.__set_path(path); - defaultSessionConnection_->pruneSchemaTemplate(req); + TSPruneSchemaTemplateReq req; + req.__set_name(template_name); + req.__set_path(path); + defaultSessionConnection_->pruneSchemaTemplate(req); } int Session::countMeasurementsInTemplate(const string& template_name) { - TSQueryTemplateReq req; - req.__set_name(template_name); - req.__set_queryType(TemplateQueryType::COUNT_MEASUREMENTS); - TSQueryTemplateResp resp = defaultSessionConnection_->querySchemaTemplate(req); - return resp.count; + TSQueryTemplateReq req; + req.__set_name(template_name); + req.__set_queryType(TemplateQueryType::COUNT_MEASUREMENTS); + TSQueryTemplateResp resp = defaultSessionConnection_->querySchemaTemplate(req); + return resp.count; } bool Session::isMeasurementInTemplate(const string& template_name, const string& path) { - TSQueryTemplateReq req; - req.__set_name(template_name); - req.__set_measurement(path); - req.__set_queryType(TemplateQueryType::IS_MEASUREMENT); - TSQueryTemplateResp resp = defaultSessionConnection_->querySchemaTemplate(req); - return resp.result; + TSQueryTemplateReq req; + req.__set_name(template_name); + req.__set_measurement(path); + req.__set_queryType(TemplateQueryType::IS_MEASUREMENT); + TSQueryTemplateResp resp = defaultSessionConnection_->querySchemaTemplate(req); + return resp.result; } bool Session::isPathExistInTemplate(const string& template_name, const string& path) { - TSQueryTemplateReq req; - req.__set_name(template_name); - req.__set_measurement(path); - req.__set_queryType(TemplateQueryType::PATH_EXIST); - TSQueryTemplateResp resp = defaultSessionConnection_->querySchemaTemplate(req); - return resp.result; + TSQueryTemplateReq req; + req.__set_name(template_name); + req.__set_measurement(path); + req.__set_queryType(TemplateQueryType::PATH_EXIST); + TSQueryTemplateResp resp = defaultSessionConnection_->querySchemaTemplate(req); + return resp.result; } std::vector Session::showMeasurementsInTemplate(const string& template_name) { - TSQueryTemplateReq req; - req.__set_name(template_name); - req.__set_measurement(""); - req.__set_queryType(TemplateQueryType::SHOW_MEASUREMENTS); - TSQueryTemplateResp resp = defaultSessionConnection_->querySchemaTemplate(req); - return resp.measurements; + TSQueryTemplateReq req; + req.__set_name(template_name); + req.__set_measurement(""); + req.__set_queryType(TemplateQueryType::SHOW_MEASUREMENTS); + TSQueryTemplateResp resp = defaultSessionConnection_->querySchemaTemplate(req); + return resp.measurements; } -std::vector Session::showMeasurementsInTemplate(const string& template_name, const string& pattern) { - TSQueryTemplateReq req; - req.__set_name(template_name); - req.__set_measurement(pattern); - req.__set_queryType(TemplateQueryType::SHOW_MEASUREMENTS); - TSQueryTemplateResp resp = defaultSessionConnection_->querySchemaTemplate(req); - return resp.measurements; +std::vector Session::showMeasurementsInTemplate(const string& template_name, + const string& pattern) { + TSQueryTemplateReq req; + req.__set_name(template_name); + req.__set_measurement(pattern); + req.__set_queryType(TemplateQueryType::SHOW_MEASUREMENTS); + TSQueryTemplateResp resp = defaultSessionConnection_->querySchemaTemplate(req); + return resp.measurements; } bool Session::checkTemplateExists(const string& template_name) { - try { - std::unique_ptr dataset = executeQueryStatement( - "SHOW NODES IN DEVICE TEMPLATE " + template_name); - bool isExisted = dataset->hasNext(); - dataset->closeOperationHandle(); - return isExisted; - } - catch (const exception& e) { - if (strstr(e.what(), "does not exist") != NULL) { - return false; - } - log_debug(e.what()); - throw IoTDBException(e.what()); - } + try { + std::unique_ptr dataset = + executeQueryStatement("SHOW NODES IN DEVICE TEMPLATE " + template_name); + bool isExisted = dataset->hasNext(); + dataset->closeOperationHandle(); + return isExisted; + } catch (const exception& e) { + if (strstr(e.what(), "does not exist") != NULL) { + return false; + } + log_debug(e.what()); + throw IoTDBException(e.what()); + } } diff --git a/iotdb-client/client-cpp/src/main/Session.h b/iotdb-client/client-cpp/src/main/Session.h index 15d0afe4d5f67..30ba60d6cad7c 100644 --- a/iotdb-client/client-cpp/src/main/Session.h +++ b/iotdb-client/client-cpp/src/main/Session.h @@ -53,19 +53,17 @@ using namespace std; +using ::apache::thrift::TException; using ::apache::thrift::protocol::TBinaryProtocol; using ::apache::thrift::protocol::TCompactProtocol; +using ::apache::thrift::transport::TBufferedTransport; +using ::apache::thrift::transport::TFramedTransport; using ::apache::thrift::transport::TSocket; using ::apache::thrift::transport::TTransport; using ::apache::thrift::transport::TTransportException; -using ::apache::thrift::transport::TBufferedTransport; -using ::apache::thrift::transport::TFramedTransport; -using ::apache::thrift::TException; - -template -void safe_cast(const T& value, Target& target) { - /* +template void safe_cast(const T& value, Target& target) { + /* Target Allowed Source Types BOOLEAN BOOLEAN INT32 INT32 @@ -74,39 +72,32 @@ void safe_cast(const T& value, Target& target) { DOUBLE INT32 INT64 FLOAT DOUBLE TEXT TEXT */ - if (std::is_same::value) { - target = *(Target*)&value; - } - else if (std::is_same::value && std::is_array::value && std::is_same< - char, typename std::remove_extent::type>::value) { - string tmp((const char*)&value); - target = *(Target*)&tmp; - } - else if (std::is_same::value && std::is_same::value) { - int64_t tmp = *(int32_t*)&value; - target = *(Target*)&tmp; - } - else if (std::is_same::value && std::is_same::value) { - float tmp = *(int32_t*)&value; - target = *(Target*)&tmp; - } - else if (std::is_same::value && std::is_same::value) { - double tmp = *(int32_t*)&value; - target = *(Target*)&tmp; - } - else if (std::is_same::value && std::is_same::value) { - double tmp = *(int64_t*)&value; - target = *(Target*)&tmp; - } - else if (std::is_same::value && std::is_same::value) { - double tmp = *(float*)&value; - target = *(Target*)&tmp; - } - else { - throw UnSupportedDataTypeException("Error: Parameter type " + - std::string(typeid(T).name()) + " cannot be converted to DataType" + - std::string(typeid(Target).name())); - } + if (std::is_same::value) { + target = *(Target*)&value; + } else if (std::is_same::value && std::is_array::value && + std::is_same::type>::value) { + string tmp((const char*)&value); + target = *(Target*)&tmp; + } else if (std::is_same::value && std::is_same::value) { + int64_t tmp = *(int32_t*)&value; + target = *(Target*)&tmp; + } else if (std::is_same::value && std::is_same::value) { + float tmp = *(int32_t*)&value; + target = *(Target*)&tmp; + } else if (std::is_same::value && std::is_same::value) { + double tmp = *(int32_t*)&value; + target = *(Target*)&tmp; + } else if (std::is_same::value && std::is_same::value) { + double tmp = *(int64_t*)&value; + target = *(Target*)&tmp; + } else if (std::is_same::value && std::is_same::value) { + double tmp = *(float*)&value; + target = *(Target*)&tmp; + } else { + throw UnSupportedDataTypeException("Error: Parameter type " + std::string(typeid(T).name()) + + " cannot be converted to DataType" + + std::string(typeid(Target).name())); + } } /* @@ -125,46 +116,46 @@ void safe_cast(const T& value, Target& target) { */ class Tablet { private: - static const int DEFAULT_ROW_SIZE = 1024; + static const int DEFAULT_ROW_SIZE = 1024; - void createColumns(); - void deleteColumns(); + void createColumns(); + void deleteColumns(); public: - std::string deviceId; // deviceId of this tablet - std::vector> schemas; - // the list of measurement schemas for creating the tablet - std::map schemaNameIndex; // the map of schema name to index - std::vector columnTypes; // the list of column types (used in table model) - std::vector timestamps; // timestamps in this tablet - std::vector values; // each object is a primitive type array, which represents values of one measurement - std::vector bitMaps; // each bitmap represents the existence of each value in the current column - size_t rowSize; //the number of rows to include in this tablet - size_t maxRowNumber; // the maximum number of rows for this tablet - bool isAligned; // whether this tablet store data of aligned timeseries or not - std::vector idColumnIndexes; - - Tablet() = default; - - /** + std::string deviceId; // deviceId of this tablet + std::vector> schemas; + // the list of measurement schemas for creating the tablet + std::map schemaNameIndex; // the map of schema name to index + std::vector columnTypes; // the list of column types (used in table model) + std::vector timestamps; // timestamps in this tablet + std::vector + values; // each object is a primitive type array, which represents values of one measurement + std::vector + bitMaps; // each bitmap represents the existence of each value in the current column + size_t rowSize; //the number of rows to include in this tablet + size_t maxRowNumber; // the maximum number of rows for this tablet + bool isAligned; // whether this tablet store data of aligned timeseries or not + std::vector idColumnIndexes; + + Tablet() = default; + + /** * Return a tablet with default specified row number. This is the standard * constructor (all Tablet should be the same size). * * @param deviceId the name of the device specified to be written in * @param timeseries the list of measurement schemas for creating the tablet */ - Tablet(const std::string& deviceId, - const std::vector>& timeseries) - : Tablet(deviceId, timeseries, DEFAULT_ROW_SIZE) { - } + Tablet(const std::string& deviceId, + const std::vector>& timeseries) + : Tablet(deviceId, timeseries, DEFAULT_ROW_SIZE) {} - Tablet(const std::string& deviceId, - const std::vector>& timeseries, - const std::vector& columnTypes) - : Tablet(deviceId, timeseries, columnTypes, DEFAULT_ROW_SIZE) { - } + Tablet(const std::string& deviceId, + const std::vector>& timeseries, + const std::vector& columnTypes) + : Tablet(deviceId, timeseries, columnTypes, DEFAULT_ROW_SIZE) {} - /** + /** * Return a tablet with the specified number of rows (maxBatchSize). Only * call this constructor directly for testing purposes. Tablet should normally * always be default size. @@ -175,918 +166,921 @@ class Tablet { * @param columnTypes the list of column types (used in table model) * @param maxRowNumber the maximum number of rows for this tablet */ - Tablet(const std::string& deviceId, - const std::vector>& schemas, - int maxRowNumber) - : Tablet(deviceId, schemas, std::vector(schemas.size(), ColumnCategory::FIELD), maxRowNumber) { + Tablet(const std::string& deviceId, + const std::vector>& schemas, + int maxRowNumber) + : Tablet(deviceId, schemas, + std::vector(schemas.size(), ColumnCategory::FIELD), maxRowNumber) {} + + Tablet(const std::string& deviceId, + const std::vector>& schemas, + const std::vector columnTypes, size_t maxRowNumber, + bool _isAligned = false) + : deviceId(deviceId), schemas(schemas), columnTypes(columnTypes), maxRowNumber(maxRowNumber), + isAligned(_isAligned) { + // create timestamp column + timestamps.resize(maxRowNumber); + // create value columns + values.resize(schemas.size()); + createColumns(); + // init idColumnIndexs + for (size_t i = 0; i < this->columnTypes.size(); i++) { + if (this->columnTypes[i] == ColumnCategory::TAG) { + idColumnIndexes.push_back(i); + } } - - Tablet(const std::string& deviceId, const std::vector>& schemas, - const std::vector columnTypes, - size_t maxRowNumber, bool _isAligned = false) : deviceId(deviceId), schemas(schemas), - columnTypes(columnTypes), - maxRowNumber(maxRowNumber), isAligned(_isAligned) { - // create timestamp column - timestamps.resize(maxRowNumber); - // create value columns - values.resize(schemas.size()); - createColumns(); - // init idColumnIndexs - for (size_t i = 0; i < this->columnTypes.size(); i++) { - if (this->columnTypes[i] == ColumnCategory::TAG) { - idColumnIndexes.push_back(i); - } - } - // create bitMaps - bitMaps.resize(schemas.size()); - for (size_t i = 0; i < schemas.size(); i++) { - bitMaps[i].resize(maxRowNumber); - } - // create schemaNameIndex - for (size_t i = 0; i < schemas.size(); i++) { - schemaNameIndex[schemas[i].first] = i; - } - this->rowSize = 0; + // create bitMaps + bitMaps.resize(schemas.size()); + for (size_t i = 0; i < schemas.size(); i++) { + bitMaps[i].resize(maxRowNumber); } - - Tablet(const Tablet& other) - : deviceId(other.deviceId), - schemas(other.schemas), - schemaNameIndex(other.schemaNameIndex), - columnTypes(other.columnTypes), - timestamps(other.timestamps), - maxRowNumber(other.maxRowNumber), - bitMaps(other.bitMaps), - rowSize(other.rowSize), - isAligned(other.isAligned), - idColumnIndexes(other.idColumnIndexes) { - values.resize(other.values.size()); - for (size_t i = 0; i < other.values.size(); ++i) { - if (!other.values[i]) continue; - TSDataType::TSDataType type = schemas[i].second; - deepCopyTabletColValue(&(other.values[i]), &values[i], type, maxRowNumber); - } + // create schemaNameIndex + for (size_t i = 0; i < schemas.size(); i++) { + schemaNameIndex[schemas[i].first] = i; } - - Tablet& operator=(const Tablet& other) { - if (this != &other) { - deleteColumns(); - deviceId = other.deviceId; - schemas = other.schemas; - schemaNameIndex = other.schemaNameIndex; - columnTypes = other.columnTypes; - timestamps = other.timestamps; - maxRowNumber = other.maxRowNumber; - rowSize = other.rowSize; - isAligned = other.isAligned; - idColumnIndexes = other.idColumnIndexes; - bitMaps = other.bitMaps; - values.resize(other.values.size()); - for (size_t i = 0; i < other.values.size(); ++i) { - if (!other.values[i]) continue; - TSDataType::TSDataType type = schemas[i].second; - deepCopyTabletColValue(&(other.values[i]), &values[i], type, maxRowNumber); - } - } - return *this; + this->rowSize = 0; + } + + Tablet(const Tablet& other) + : deviceId(other.deviceId), schemas(other.schemas), schemaNameIndex(other.schemaNameIndex), + columnTypes(other.columnTypes), timestamps(other.timestamps), + maxRowNumber(other.maxRowNumber), bitMaps(other.bitMaps), rowSize(other.rowSize), + isAligned(other.isAligned), idColumnIndexes(other.idColumnIndexes) { + values.resize(other.values.size()); + for (size_t i = 0; i < other.values.size(); ++i) { + if (!other.values[i]) + continue; + TSDataType::TSDataType type = schemas[i].second; + deepCopyTabletColValue(&(other.values[i]), &values[i], type, maxRowNumber); } - - ~Tablet() { - try { - deleteColumns(); - } - catch (exception& e) { - log_debug(string("Tablet::~Tablet(), ") + e.what()); - } + } + + Tablet& operator=(const Tablet& other) { + if (this != &other) { + deleteColumns(); + deviceId = other.deviceId; + schemas = other.schemas; + schemaNameIndex = other.schemaNameIndex; + columnTypes = other.columnTypes; + timestamps = other.timestamps; + maxRowNumber = other.maxRowNumber; + rowSize = other.rowSize; + isAligned = other.isAligned; + idColumnIndexes = other.idColumnIndexes; + bitMaps = other.bitMaps; + values.resize(other.values.size()); + for (size_t i = 0; i < other.values.size(); ++i) { + if (!other.values[i]) + continue; + TSDataType::TSDataType type = schemas[i].second; + deepCopyTabletColValue(&(other.values[i]), &values[i], type, maxRowNumber); + } } + return *this; + } - void addTimestamp(size_t rowIndex, int64_t timestamp) { - timestamps[rowIndex] = timestamp; - rowSize = max(rowSize, rowIndex + 1); + ~Tablet() { + try { + deleteColumns(); + } catch (exception& e) { + log_debug(string("Tablet::~Tablet(), ") + e.what()); + } + } + + void addTimestamp(size_t rowIndex, int64_t timestamp) { + timestamps[rowIndex] = timestamp; + rowSize = max(rowSize, rowIndex + 1); + } + + static void deepCopyTabletColValue(void* const* srcPtr, void** destPtr, + TSDataType::TSDataType type, int maxRowNumber); + + template void addValue(size_t schemaId, size_t rowIndex, const T& value) { + if (schemaId >= schemas.size()) { + char tmpStr[100]; + sprintf(tmpStr, + "Tablet::addValue(), schemaId >= schemas.size(). schemaId=%ld, schemas.size()=%ld.", + schemaId, schemas.size()); + throw std::out_of_range(tmpStr); } - static void deepCopyTabletColValue(void* const* srcPtr, void** destPtr, - TSDataType::TSDataType type, int maxRowNumber); - - template - void addValue(size_t schemaId, size_t rowIndex, const T& value) { - if (schemaId >= schemas.size()) { - char tmpStr[100]; - sprintf(tmpStr, "Tablet::addValue(), schemaId >= schemas.size(). schemaId=%ld, schemas.size()=%ld.", - schemaId, schemas.size()); - throw std::out_of_range(tmpStr); - } - - if (rowIndex >= rowSize) { - char tmpStr[100]; - sprintf(tmpStr, "Tablet::addValue(), rowIndex >= rowSize. rowIndex=%ld, rowSize.size()=%ld.", rowIndex, - rowSize); - throw std::out_of_range(tmpStr); - } + if (rowIndex >= rowSize) { + char tmpStr[100]; + sprintf(tmpStr, "Tablet::addValue(), rowIndex >= rowSize. rowIndex=%ld, rowSize.size()=%ld.", + rowIndex, rowSize); + throw std::out_of_range(tmpStr); + } - TSDataType::TSDataType dataType = schemas[schemaId].second; - switch (dataType) { - case TSDataType::BOOLEAN: { - safe_cast(value, ((bool*)values[schemaId])[rowIndex]); - break; - } - case TSDataType::INT32: { - safe_cast(value, ((int*)values[schemaId])[rowIndex]); - break; - } - case TSDataType::DATE: { - safe_cast(value, ((boost::gregorian::date*)values[schemaId])[rowIndex]); - break; - } - case TSDataType::TIMESTAMP: - case TSDataType::INT64: { - safe_cast(value, ((int64_t*)values[schemaId])[rowIndex]); - break; - } - case TSDataType::FLOAT: { - safe_cast(value, ((float*)values[schemaId])[rowIndex]); - break; - } - case TSDataType::DOUBLE: { - safe_cast(value, ((double*)values[schemaId])[rowIndex]); - break; - } - case TSDataType::BLOB: - case TSDataType::STRING: - case TSDataType::TEXT: { - safe_cast(value, ((string*)values[schemaId])[rowIndex]); - break; - } - default: - throw UnSupportedDataTypeException(string("Data type ") + to_string(dataType) + " is not supported."); - } + TSDataType::TSDataType dataType = schemas[schemaId].second; + switch (dataType) { + case TSDataType::BOOLEAN: { + safe_cast(value, ((bool*)values[schemaId])[rowIndex]); + break; + } + case TSDataType::INT32: { + safe_cast(value, ((int*)values[schemaId])[rowIndex]); + break; + } + case TSDataType::DATE: { + safe_cast(value, + ((boost::gregorian::date*)values[schemaId])[rowIndex]); + break; + } + case TSDataType::TIMESTAMP: + case TSDataType::INT64: { + safe_cast(value, ((int64_t*)values[schemaId])[rowIndex]); + break; + } + case TSDataType::FLOAT: { + safe_cast(value, ((float*)values[schemaId])[rowIndex]); + break; + } + case TSDataType::DOUBLE: { + safe_cast(value, ((double*)values[schemaId])[rowIndex]); + break; + } + case TSDataType::BLOB: + case TSDataType::STRING: + case TSDataType::TEXT: { + safe_cast(value, ((string*)values[schemaId])[rowIndex]); + break; + } + default: + throw UnSupportedDataTypeException(string("Data type ") + to_string(dataType) + + " is not supported."); + } + } + + // Add a Binary value with extra metadata: [isEOF (1 byte)] + [offset (8 bytes)] + [actual content] + void addValue(size_t schemaId, size_t rowIndex, bool isEOF, int64_t offset, + const std::vector& content) { + // Check schemaId bounds + if (schemaId >= schemas.size()) { + char tmpStr[100]; + sprintf(tmpStr, + "Tablet::addBinaryValueWithMeta(), schemaId >= schemas.size(). schemaId=%ld, " + "schemas.size()=%ld.", + schemaId, schemas.size()); + throw std::out_of_range(tmpStr); } - // Add a Binary value with extra metadata: [isEOF (1 byte)] + [offset (8 bytes)] + [actual content] - void addValue(size_t schemaId, size_t rowIndex, bool isEOF, int64_t offset, const std::vector& content) { - // Check schemaId bounds - if (schemaId >= schemas.size()) { - char tmpStr[100]; - sprintf(tmpStr, - "Tablet::addBinaryValueWithMeta(), schemaId >= schemas.size(). schemaId=%ld, schemas.size()=%ld.", - schemaId, schemas.size()); - throw std::out_of_range(tmpStr); - } + // Check rowIndex bounds + if (rowIndex >= rowSize) { + char tmpStr[100]; + sprintf(tmpStr, + "Tablet::addBinaryValueWithMeta(), rowIndex >= rowSize. rowIndex=%ld, rowSize=%ld.", + rowIndex, rowSize); + throw std::out_of_range(tmpStr); + } - // Check rowIndex bounds - if (rowIndex >= rowSize) { - char tmpStr[100]; - sprintf(tmpStr, "Tablet::addBinaryValueWithMeta(), rowIndex >= rowSize. rowIndex=%ld, rowSize=%ld.", - rowIndex, rowSize); - throw std::out_of_range(tmpStr); - } + TSDataType::TSDataType dataType = schemas[schemaId].second; + if (dataType != TSDataType::OBJECT) { + throw std::invalid_argument("The data type of schemaId " + std::to_string(schemaId) + + " is not OBJECT."); + } - TSDataType::TSDataType dataType = schemas[schemaId].second; - if (dataType != TSDataType::OBJECT) { - throw std::invalid_argument("The data type of schemaId " + std::to_string(schemaId) + " is not OBJECT."); - } + // Create a byte array of size [1 (isEOF) + 8 (offset) + content size] + std::vector val(content.size() + 9); - // Create a byte array of size [1 (isEOF) + 8 (offset) + content size] - std::vector val(content.size() + 9); + // Write the isEOF flag (1 byte) + val[0] = isEOF ? 1 : 0; - // Write the isEOF flag (1 byte) - val[0] = isEOF ? 1 : 0; + // Write the 8-byte offset in big-endian order + for (int i = 0; i < 8; ++i) { + val[1 + i] = static_cast((offset >> (56 - i * 8)) & 0xFF); + } - // Write the 8-byte offset in big-endian order - for (int i = 0; i < 8; ++i) { - val[1 + i] = static_cast((offset >> (56 - i * 8)) & 0xFF); - } + // Append the content bytes + std::copy(content.begin(), content.end(), val.begin() + 9); - // Append the content bytes - std::copy(content.begin(), content.end(), val.begin() + 9); + // Cast the value array and assign the Binary data (stored as string) + std::string valEncoded = std::string(reinterpret_cast(val.data()), val.size()); + safe_cast(valEncoded, ((string*)values[schemaId])[rowIndex]); + } - // Cast the value array and assign the Binary data (stored as string) - std::string valEncoded = std::string(reinterpret_cast(val.data()), val.size()); - safe_cast(valEncoded, ((string*)values[schemaId])[rowIndex]); + void addValue(const string& schemaName, size_t rowIndex, bool isEOF, int64_t offset, + const std::vector& content) { + if (schemaNameIndex.find(schemaName) == schemaNameIndex.end()) { + throw SchemaNotFoundException(string("Schema ") + schemaName + " not found."); } + size_t schemaId = schemaNameIndex[schemaName]; + addValue(schemaId, rowIndex, isEOF, offset, content); + } - void addValue(const string& schemaName, size_t rowIndex, bool isEOF, int64_t offset, - const std::vector& content) { - if (schemaNameIndex.find(schemaName) == schemaNameIndex.end()) { - throw SchemaNotFoundException(string("Schema ") + schemaName + " not found."); - } - size_t schemaId = schemaNameIndex[schemaName]; - addValue(schemaId, rowIndex, isEOF, offset, content); + template void addValue(const string& schemaName, size_t rowIndex, const T& value) { + if (schemaNameIndex.find(schemaName) == schemaNameIndex.end()) { + throw SchemaNotFoundException(string("Schema ") + schemaName + " not found."); } - - template - void addValue(const string& schemaName, size_t rowIndex, const T& value) { - if (schemaNameIndex.find(schemaName) == schemaNameIndex.end()) { - throw SchemaNotFoundException(string("Schema ") + schemaName + " not found."); - } - size_t schemaId = schemaNameIndex[schemaName]; - addValue(schemaId, rowIndex, value); + size_t schemaId = schemaNameIndex[schemaName]; + addValue(schemaId, rowIndex, value); + } + + void* getValue(size_t schemaId, size_t rowIndex, TSDataType::TSDataType dataType) { + if (schemaId >= schemas.size()) { + throw std::out_of_range("Tablet::getValue schemaId out of range: " + + std::to_string(schemaId)); + } + if (rowIndex >= rowSize) { + throw std::out_of_range("Tablet::getValue rowIndex out of range: " + + std::to_string(rowIndex)); } - void* getValue(size_t schemaId, size_t rowIndex, TSDataType::TSDataType dataType) { - if (schemaId >= schemas.size()) { - throw std::out_of_range("Tablet::getValue schemaId out of range: " - + std::to_string(schemaId)); - } - if (rowIndex >= rowSize) { - throw std::out_of_range("Tablet::getValue rowIndex out of range: " - + std::to_string(rowIndex)); - } - - switch (dataType) { - case TSDataType::BOOLEAN: - return &(reinterpret_cast(values[schemaId])[rowIndex]); - case TSDataType::INT32: - return &(reinterpret_cast(values[schemaId])[rowIndex]); - case TSDataType::DATE: - return &(reinterpret_cast(values[schemaId])[rowIndex]); - case TSDataType::TIMESTAMP: - case TSDataType::INT64: - return &(reinterpret_cast(values[schemaId])[rowIndex]); - case TSDataType::FLOAT: - return &(reinterpret_cast(values[schemaId])[rowIndex]); - case TSDataType::DOUBLE: - return &(reinterpret_cast(values[schemaId])[rowIndex]); - case TSDataType::BLOB: - case TSDataType::STRING: - case TSDataType::OBJECT: - case TSDataType::TEXT: - return &(reinterpret_cast(values[schemaId])[rowIndex]); - default: - throw UnSupportedDataTypeException("Unsupported data type: " - + std::to_string(dataType)); - } + switch (dataType) { + case TSDataType::BOOLEAN: + return &(reinterpret_cast(values[schemaId])[rowIndex]); + case TSDataType::INT32: + return &(reinterpret_cast(values[schemaId])[rowIndex]); + case TSDataType::DATE: + return &(reinterpret_cast(values[schemaId])[rowIndex]); + case TSDataType::TIMESTAMP: + case TSDataType::INT64: + return &(reinterpret_cast(values[schemaId])[rowIndex]); + case TSDataType::FLOAT: + return &(reinterpret_cast(values[schemaId])[rowIndex]); + case TSDataType::DOUBLE: + return &(reinterpret_cast(values[schemaId])[rowIndex]); + case TSDataType::BLOB: + case TSDataType::STRING: + case TSDataType::OBJECT: + case TSDataType::TEXT: + return &(reinterpret_cast(values[schemaId])[rowIndex]); + default: + throw UnSupportedDataTypeException("Unsupported data type: " + std::to_string(dataType)); } + } - std::shared_ptr getDeviceID(int i); + std::shared_ptr getDeviceID(int i); - std::vector> getSchemas() const { - return schemas; - } + std::vector> getSchemas() const { + return schemas; + } - void reset(); // Reset Tablet to the default state - set the rowSize to 0 + void reset(); // Reset Tablet to the default state - set the rowSize to 0 - size_t getTimeBytesSize(); + size_t getTimeBytesSize(); - size_t getValueByteSize(); // total byte size that values occupies + size_t getValueByteSize(); // total byte size that values occupies - void setAligned(bool isAligned); + void setAligned(bool isAligned); }; class SessionUtils { public: - static std::string getTime(const Tablet& tablet); + static std::string getTime(const Tablet& tablet); - static std::string getValue(const Tablet& tablet); + static std::string getValue(const Tablet& tablet); - static bool isTabletContainsSingleDevice(Tablet tablet); + static bool isTabletContainsSingleDevice(Tablet tablet); }; class TemplateNode { public: - explicit TemplateNode(const std::string& name) : name_(name) { - } + explicit TemplateNode(const std::string& name) : name_(name) {} - const std::string& getName() const { - return name_; - } + const std::string& getName() const { + return name_; + } - virtual const std::unordered_map>& getChildren() const { - throw BatchExecutionException("Should call exact sub class!"); - } + virtual const std::unordered_map>& + getChildren() const { + throw BatchExecutionException("Should call exact sub class!"); + } - virtual bool isMeasurement() = 0; + virtual bool isMeasurement() = 0; - virtual bool isAligned() { - throw BatchExecutionException("Should call exact sub class!"); - } + virtual bool isAligned() { + throw BatchExecutionException("Should call exact sub class!"); + } - virtual std::string serialize() const { - throw BatchExecutionException("Should call exact sub class!"); - } + virtual std::string serialize() const { + throw BatchExecutionException("Should call exact sub class!"); + } private: - std::string name_; + std::string name_; }; class MeasurementNode : public TemplateNode { public: - MeasurementNode(const std::string& name_, TSDataType::TSDataType data_type_, TSEncoding::TSEncoding encoding_, - CompressionType::CompressionType compression_type_) : TemplateNode(name_) { - this->data_type_ = data_type_; - this->encoding_ = encoding_; - this->compression_type_ = compression_type_; - } + MeasurementNode(const std::string& name_, TSDataType::TSDataType data_type_, + TSEncoding::TSEncoding encoding_, + CompressionType::CompressionType compression_type_) + : TemplateNode(name_) { + this->data_type_ = data_type_; + this->encoding_ = encoding_; + this->compression_type_ = compression_type_; + } - TSDataType::TSDataType getDataType() const { - return data_type_; - } + TSDataType::TSDataType getDataType() const { + return data_type_; + } - TSEncoding::TSEncoding getEncoding() const { - return encoding_; - } + TSEncoding::TSEncoding getEncoding() const { + return encoding_; + } - CompressionType::CompressionType getCompressionType() const { - return compression_type_; - } + CompressionType::CompressionType getCompressionType() const { + return compression_type_; + } - bool isMeasurement() override { - return true; - } + bool isMeasurement() override { + return true; + } - std::string serialize() const override; + std::string serialize() const override; private: - TSDataType::TSDataType data_type_; - TSEncoding::TSEncoding encoding_; - CompressionType::CompressionType compression_type_; + TSDataType::TSDataType data_type_; + TSEncoding::TSEncoding encoding_; + CompressionType::CompressionType compression_type_; }; class InternalNode : public TemplateNode { public: - InternalNode(const std::string& name, bool is_aligned) : TemplateNode(name), is_aligned_(is_aligned) { - } + InternalNode(const std::string& name, bool is_aligned) + : TemplateNode(name), is_aligned_(is_aligned) {} - void addChild(const InternalNode& node) { - if (this->children_.count(node.getName())) { - throw BatchExecutionException("Duplicated child of node in template."); - } - this->children_[node.getName()] = std::make_shared(node); + void addChild(const InternalNode& node) { + if (this->children_.count(node.getName())) { + throw BatchExecutionException("Duplicated child of node in template."); } + this->children_[node.getName()] = std::make_shared(node); + } - void addChild(const MeasurementNode& node) { - if (this->children_.count(node.getName())) { - throw BatchExecutionException("Duplicated child of node in template."); - } - this->children_[node.getName()] = std::make_shared(node); + void addChild(const MeasurementNode& node) { + if (this->children_.count(node.getName())) { + throw BatchExecutionException("Duplicated child of node in template."); } + this->children_[node.getName()] = std::make_shared(node); + } - void deleteChild(const TemplateNode& node) { - this->children_.erase(node.getName()); - } + void deleteChild(const TemplateNode& node) { + this->children_.erase(node.getName()); + } - const std::unordered_map>& getChildren() const override { - return children_; - } + const std::unordered_map>& + getChildren() const override { + return children_; + } - bool isMeasurement() override { - return false; - } + bool isMeasurement() override { + return false; + } - bool isAligned() override { - return is_aligned_; - } + bool isAligned() override { + return is_aligned_; + } private: - std::unordered_map> children_; - bool is_aligned_; + std::unordered_map> children_; + bool is_aligned_; }; namespace TemplateQueryType { -enum TemplateQueryType { - COUNT_MEASUREMENTS, IS_MEASUREMENT, PATH_EXIST, SHOW_MEASUREMENTS -}; +enum TemplateQueryType { COUNT_MEASUREMENTS, IS_MEASUREMENT, PATH_EXIST, SHOW_MEASUREMENTS }; } class Template { public: - Template(const std::string& name, bool is_aligned) : name_(name), is_aligned_(is_aligned) { - } + Template(const std::string& name, bool is_aligned) : name_(name), is_aligned_(is_aligned) {} - const std::string& getName() const { - return name_; - } + const std::string& getName() const { + return name_; + } - bool isAligned() const { - return is_aligned_; - } + bool isAligned() const { + return is_aligned_; + } - void addToTemplate(const InternalNode& child) { - if (this->children_.count(child.getName())) { - throw BatchExecutionException("Duplicated child of node in template."); - } - this->children_[child.getName()] = std::make_shared(child); + void addToTemplate(const InternalNode& child) { + if (this->children_.count(child.getName())) { + throw BatchExecutionException("Duplicated child of node in template."); } + this->children_[child.getName()] = std::make_shared(child); + } - void addToTemplate(const MeasurementNode& child) { - if (this->children_.count(child.getName())) { - throw BatchExecutionException("Duplicated child of node in template."); - } - this->children_[child.getName()] = std::make_shared(child); + void addToTemplate(const MeasurementNode& child) { + if (this->children_.count(child.getName())) { + throw BatchExecutionException("Duplicated child of node in template."); } + this->children_[child.getName()] = std::make_shared(child); + } - std::string serialize() const; + std::string serialize() const; private: - std::string name_; - std::unordered_map> children_; - bool is_aligned_; + std::string name_; + std::unordered_map> children_; + bool is_aligned_; }; class Session { private: - std::string host_; - int rpcPort_; - bool useSSL_ = false; - std::string trustCertFilePath_; - std::vector nodeUrls_; - std::string username_; - std::string password_; - const TSProtocolVersion::type protocolVersion_ = TSProtocolVersion::IOTDB_SERVICE_PROTOCOL_V3; - bool isClosed_ = true; - std::string zoneId_; - int fetchSize_; - const static int DEFAULT_FETCH_SIZE = 10000; - const static int DEFAULT_TIMEOUT_MS = 0; - int connectTimeoutMs_; - Version::Version version; - std::string sqlDialect_ = "tree"; // default sql dialect - std::string database_; - bool enableAutoFetch_ = true; - bool enableRedirection_ = true; - std::shared_ptr nodesSupplier_; - friend class SessionConnection; - friend class TableSession; - std::shared_ptr defaultSessionConnection_; - - TEndPoint defaultEndPoint_; - - struct TEndPointHash { - size_t operator()(const TEndPoint& endpoint) const { - return std::hash()(endpoint.ip) ^ std::hash()(endpoint.port); - } - }; + std::string host_; + int rpcPort_; + bool useSSL_ = false; + std::string trustCertFilePath_; + std::vector nodeUrls_; + std::string username_; + std::string password_; + const TSProtocolVersion::type protocolVersion_ = TSProtocolVersion::IOTDB_SERVICE_PROTOCOL_V3; + bool isClosed_ = true; + std::string zoneId_; + int fetchSize_; + const static int DEFAULT_FETCH_SIZE = 10000; + const static int DEFAULT_TIMEOUT_MS = 0; + int connectTimeoutMs_; + Version::Version version; + std::string sqlDialect_ = "tree"; // default sql dialect + std::string database_; + bool enableAutoFetch_ = true; + bool enableRedirection_ = true; + std::shared_ptr nodesSupplier_; + friend class SessionConnection; + friend class TableSession; + std::shared_ptr defaultSessionConnection_; + + TEndPoint defaultEndPoint_; + + struct TEndPointHash { + size_t operator()(const TEndPoint& endpoint) const { + return std::hash()(endpoint.ip) ^ std::hash()(endpoint.port); + } + }; - struct TEndPointEqual { - bool operator()(const TEndPoint& lhs, const TEndPoint& rhs) const { - return lhs.ip == rhs.ip && lhs.port == rhs.port; - } - }; + struct TEndPointEqual { + bool operator()(const TEndPoint& lhs, const TEndPoint& rhs) const { + return lhs.ip == rhs.ip && lhs.port == rhs.port; + } + }; - using EndPointSessionMap = std::unordered_map< - TEndPoint, shared_ptr, TEndPointHash, TEndPointEqual>; - EndPointSessionMap endPointToSessionConnection; - std::unordered_map deviceIdToEndpoint; - std::unordered_map, TEndPoint> tableModelDeviceIdToEndpoint; + using EndPointSessionMap = + std::unordered_map, TEndPointHash, TEndPointEqual>; + EndPointSessionMap endPointToSessionConnection; + std::unordered_map deviceIdToEndpoint; + std::unordered_map, TEndPoint> tableModelDeviceIdToEndpoint; private: - void removeBrokenSessionConnection(shared_ptr sessionConnection); + void removeBrokenSessionConnection(shared_ptr sessionConnection); - static bool checkSorted(const Tablet& tablet); + static bool checkSorted(const Tablet& tablet); - static bool checkSorted(const std::vector& times); + static bool checkSorted(const std::vector& times); - static void sortTablet(Tablet& tablet); + static void sortTablet(Tablet& tablet); - static void sortIndexByTimestamp(int* index, std::vector& timestamps, int length); + static void sortIndexByTimestamp(int* index, std::vector& timestamps, int length); - void appendValues(std::string& buffer, const char* value, int size); + void appendValues(std::string& buffer, const char* value, int size); - void - putValuesIntoBuffer(const std::vector& types, const std::vector& values, - std::string& buf); + void putValuesIntoBuffer(const std::vector& types, + const std::vector& values, std::string& buf); - int8_t getDataTypeNumber(TSDataType::TSDataType type); + int8_t getDataTypeNumber(TSDataType::TSDataType type); - struct TsCompare { - std::vector& timestamps; + struct TsCompare { + std::vector& timestamps; - explicit TsCompare(std::vector& inTimestamps) : timestamps(inTimestamps) { - }; + explicit TsCompare(std::vector& inTimestamps) : timestamps(inTimestamps){}; - bool operator()(int i, int j) { return (timestamps[i] < timestamps[j]); }; + bool operator()(int i, int j) { + return (timestamps[i] < timestamps[j]); }; + }; - std::string getVersionString(Version::Version version); + std::string getVersionString(Version::Version version); - void initZoneId(); + void initZoneId(); - void initNodesSupplier(const std::vector& nodeUrls = std::vector()); + void initNodesSupplier(const std::vector& nodeUrls = std::vector()); - void initDefaultSessionConnection(); + void initDefaultSessionConnection(); - template - void insertByGroup(std::unordered_map, T>& insertGroup, - InsertConsumer insertConsumer); + template + void insertByGroup(std::unordered_map, T>& insertGroup, + InsertConsumer insertConsumer); - template - void insertOnce(std::unordered_map, T>& insertGroup, - InsertConsumer insertConsumer); + template + void insertOnce(std::unordered_map, T>& insertGroup, + InsertConsumer insertConsumer); - void insertStringRecordsWithLeaderCache(vector deviceIds, vector times, - vector> measurementsList, vector> valuesList, - bool isAligned); + void insertStringRecordsWithLeaderCache(vector deviceIds, vector times, + vector> measurementsList, + vector> valuesList, bool isAligned); - void insertRecordsWithLeaderCache(vector deviceIds, vector times, - vector> measurementsList, - const vector>& typesList, - vector> valuesList, bool isAligned); + void insertRecordsWithLeaderCache(vector deviceIds, vector times, + vector> measurementsList, + const vector>& typesList, + vector> valuesList, bool isAligned); - void insertTabletsWithLeaderCache(unordered_map tablets, bool sorted, bool isAligned); + void insertTabletsWithLeaderCache(unordered_map tablets, bool sorted, + bool isAligned); - shared_ptr getQuerySessionConnection(); + shared_ptr getQuerySessionConnection(); - shared_ptr getSessionConnection(std::string deviceId); + shared_ptr getSessionConnection(std::string deviceId); - shared_ptr getSessionConnection(std::shared_ptr deviceId); + shared_ptr getSessionConnection(std::shared_ptr deviceId); - void handleQueryRedirection(TEndPoint endPoint); + void handleQueryRedirection(TEndPoint endPoint); - void handleRedirection(const std::string& deviceId, TEndPoint endPoint); + void handleRedirection(const std::string& deviceId, TEndPoint endPoint); - void handleRedirection(const std::shared_ptr& deviceId, TEndPoint endPoint); + void handleRedirection(const std::shared_ptr& deviceId, TEndPoint endPoint); - void setSqlDialect(const std::string& dialect) { - this->sqlDialect_ = dialect; - } + void setSqlDialect(const std::string& dialect) { + this->sqlDialect_ = dialect; + } - void setDatabase(const std::string& database) { - this->database_ = database; - } + void setDatabase(const std::string& database) { + this->database_ = database; + } - string getDatabase() { - return database_; - } + string getDatabase() { + return database_; + } - void changeDatabase(string database) { - this->database_ = database; - } + void changeDatabase(string database) { + this->database_ = database; + } public: - Session(const std::string& host, int rpcPort) : username_("root"), password_("root"), version(Version::V_1_0) { - this->host_ = host; - this->rpcPort_ = rpcPort; - initZoneId(); - initNodesSupplier(); - } - - Session(const std::vector& nodeUrls, const std::string& username, const std::string& password) - : nodeUrls_(nodeUrls), username_(username), password_(password), version(Version::V_1_0) { - initZoneId(); - initNodesSupplier(this->nodeUrls_); - } + Session(const std::string& host, int rpcPort) + : username_("root"), password_("root"), version(Version::V_1_0) { + this->host_ = host; + this->rpcPort_ = rpcPort; + initZoneId(); + initNodesSupplier(); + } + + Session(const std::vector& nodeUrls, const std::string& username, + const std::string& password) + : nodeUrls_(nodeUrls), username_(username), password_(password), version(Version::V_1_0) { + initZoneId(); + initNodesSupplier(this->nodeUrls_); + } + + Session(const std::string& host, int rpcPort, const std::string& username, + const std::string& password) + : fetchSize_(DEFAULT_FETCH_SIZE) { + this->host_ = host; + this->rpcPort_ = rpcPort; + this->username_ = username; + this->password_ = password; + this->version = Version::V_1_0; + initZoneId(); + initNodesSupplier(); + } + + Session(const std::string& host, int rpcPort, const std::string& username, + const std::string& password, const std::string& zoneId, + int fetchSize = DEFAULT_FETCH_SIZE) { + this->host_ = host; + this->rpcPort_ = rpcPort; + this->username_ = username; + this->password_ = password; + this->zoneId_ = zoneId; + this->fetchSize_ = fetchSize; + this->version = Version::V_1_0; + initZoneId(); + initNodesSupplier(); + } + + Session(const std::string& host, const std::string& rpcPort, const std::string& username = "user", + const std::string& password = "password", const std::string& zoneId = "", + int fetchSize = DEFAULT_FETCH_SIZE) { + this->host_ = host; + this->rpcPort_ = stoi(rpcPort); + this->username_ = username; + this->password_ = password; + this->zoneId_ = zoneId; + this->fetchSize_ = fetchSize; + this->version = Version::V_1_0; + initZoneId(); + initNodesSupplier(); + } + + Session(AbstractSessionBuilder* builder) { + this->host_ = builder->host; + this->rpcPort_ = builder->rpcPort; + this->username_ = builder->username; + this->password_ = builder->password; + this->zoneId_ = builder->zoneId; + this->fetchSize_ = builder->fetchSize; + this->version = Version::V_1_0; + this->sqlDialect_ = builder->sqlDialect; + this->database_ = builder->database; + this->enableAutoFetch_ = builder->enableAutoFetch; + this->enableRedirection_ = builder->enableRedirections; + this->connectTimeoutMs_ = builder->connectTimeoutMs; + this->nodeUrls_ = builder->nodeUrls; + this->useSSL_ = builder->useSSL; + this->trustCertFilePath_ = builder->trustCertFilePath; + initZoneId(); + initNodesSupplier(this->nodeUrls_); + } + + ~Session(); + + void open(); + + void open(bool enableRPCCompression); + + void open(bool enableRPCCompression, int connectionTimeoutInMs); + + void close(); + + void setTimeZone(const std::string& zoneId); + + std::string getTimeZone(); + + void insertRecord(const std::string& deviceId, int64_t time, + const std::vector& measurements, + const std::vector& values); + + void insertRecord(const std::string& deviceId, int64_t time, + const std::vector& measurements, + const std::vector& types, + const std::vector& values); + + void insertAlignedRecord(const std::string& deviceId, int64_t time, + const std::vector& measurements, + const std::vector& values); + + void insertAlignedRecord(const std::string& deviceId, int64_t time, + const std::vector& measurements, + const std::vector& types, + const std::vector& values); - Session(const std::string& host, int rpcPort, const std::string& username, const std::string& password) - : fetchSize_(DEFAULT_FETCH_SIZE) { - this->host_ = host; - this->rpcPort_ = rpcPort; - this->username_ = username; - this->password_ = password; - this->version = Version::V_1_0; - initZoneId(); - initNodesSupplier(); - } - - Session(const std::string& host, int rpcPort, const std::string& username, const std::string& password, - const std::string& zoneId, int fetchSize = DEFAULT_FETCH_SIZE) { - this->host_ = host; - this->rpcPort_ = rpcPort; - this->username_ = username; - this->password_ = password; - this->zoneId_ = zoneId; - this->fetchSize_ = fetchSize; - this->version = Version::V_1_0; - initZoneId(); - initNodesSupplier(); - } - - Session(const std::string& host, const std::string& rpcPort, const std::string& username = "user", - const std::string& password = "password", const std::string& zoneId = "", - int fetchSize = DEFAULT_FETCH_SIZE) { - this->host_ = host; - this->rpcPort_ = stoi(rpcPort); - this->username_ = username; - this->password_ = password; - this->zoneId_ = zoneId; - this->fetchSize_ = fetchSize; - this->version = Version::V_1_0; - initZoneId(); - initNodesSupplier(); - } - - Session(AbstractSessionBuilder* builder) { - this->host_ = builder->host; - this->rpcPort_ = builder->rpcPort; - this->username_ = builder->username; - this->password_ = builder->password; - this->zoneId_ = builder->zoneId; - this->fetchSize_ = builder->fetchSize; - this->version = Version::V_1_0; - this->sqlDialect_ = builder->sqlDialect; - this->database_ = builder->database; - this->enableAutoFetch_ = builder->enableAutoFetch; - this->enableRedirection_ = builder->enableRedirections; - this->connectTimeoutMs_ = builder->connectTimeoutMs; - this->nodeUrls_ = builder->nodeUrls; - this->useSSL_ = builder->useSSL; - this->trustCertFilePath_ = builder->trustCertFilePath; - initZoneId(); - initNodesSupplier(this->nodeUrls_); - } - - ~Session(); - - void open(); - - void open(bool enableRPCCompression); - - void open(bool enableRPCCompression, int connectionTimeoutInMs); - - void close(); - - void setTimeZone(const std::string& zoneId); - - std::string getTimeZone(); - - void insertRecord(const std::string& deviceId, int64_t time, const std::vector& measurements, - const std::vector& values); - - void insertRecord(const std::string& deviceId, int64_t time, const std::vector& measurements, - const std::vector& types, const std::vector& values); - - void insertAlignedRecord(const std::string& deviceId, int64_t time, const std::vector& measurements, - const std::vector& values); + void insertRecords(const std::vector& deviceIds, const std::vector& times, + const std::vector>& measurementsList, + const std::vector>& valuesList); - void insertAlignedRecord(const std::string& deviceId, int64_t time, const std::vector& measurements, - const std::vector& types, const std::vector& values); + void insertRecords(const std::vector& deviceIds, const std::vector& times, + const std::vector>& measurementsList, + const std::vector>& typesList, + const std::vector>& valuesList); - void insertRecords(const std::vector& deviceIds, - const std::vector& times, - const std::vector>& measurementsList, - const std::vector>& valuesList); + void insertAlignedRecords(const std::vector& deviceIds, + const std::vector& times, + const std::vector>& measurementsList, + const std::vector>& valuesList); - void insertRecords(const std::vector& deviceIds, - const std::vector& times, - const std::vector>& measurementsList, - const std::vector>& typesList, - const std::vector>& valuesList); + void insertAlignedRecords(const std::vector& deviceIds, + const std::vector& times, + const std::vector>& measurementsList, + const std::vector>& typesList, + const std::vector>& valuesList); - void insertAlignedRecords(const std::vector& deviceIds, - const std::vector& times, - const std::vector>& measurementsList, - const std::vector>& valuesList); + void insertRecordsOfOneDevice(const std::string& deviceId, std::vector& times, + std::vector>& measurementsList, + std::vector>& typesList, + std::vector>& valuesList); - void insertAlignedRecords(const std::vector& deviceIds, - const std::vector& times, - const std::vector>& measurementsList, - const std::vector>& typesList, - const std::vector>& valuesList); + void insertRecordsOfOneDevice(const std::string& deviceId, std::vector& times, + std::vector>& measurementsList, + std::vector>& typesList, + std::vector>& valuesList, bool sorted); - void insertRecordsOfOneDevice(const std::string& deviceId, - std::vector& times, - std::vector>& measurementsList, - std::vector>& typesList, - std::vector>& valuesList); + void insertAlignedRecordsOfOneDevice(const std::string& deviceId, std::vector& times, + std::vector>& measurementsList, + std::vector>& typesList, + std::vector>& valuesList); - void insertRecordsOfOneDevice(const std::string& deviceId, - std::vector& times, - std::vector>& measurementsList, - std::vector>& typesList, - std::vector>& valuesList, - bool sorted); + void insertAlignedRecordsOfOneDevice(const std::string& deviceId, std::vector& times, + std::vector>& measurementsList, + std::vector>& typesList, + std::vector>& valuesList, bool sorted); - void insertAlignedRecordsOfOneDevice(const std::string& deviceId, - std::vector& times, - std::vector>& measurementsList, - std::vector>& typesList, - std::vector>& valuesList); + void insertTablet(Tablet& tablet); - void insertAlignedRecordsOfOneDevice(const std::string& deviceId, - std::vector& times, - std::vector>& measurementsList, - std::vector>& typesList, - std::vector>& valuesList, - bool sorted); + void insertTablet(Tablet& tablet, bool sorted); - void insertTablet(Tablet& tablet); + void insertRelationalTablet(Tablet& tablet); - void insertTablet(Tablet& tablet, bool sorted); + void insertRelationalTabletOnce( + const std::unordered_map, Tablet>& relationalTabletGroup, + bool sorted); - void insertRelationalTablet(Tablet& tablet); + void insertRelationalTabletByGroup( + const std::unordered_map, Tablet>& relationalTabletGroup, + bool sorted); - void insertRelationalTabletOnce( - const std::unordered_map, Tablet>& relationalTabletGroup, - bool sorted); + void insertRelationalTablet(Tablet& tablet, bool sorted); - void insertRelationalTabletByGroup( - const std::unordered_map, Tablet>& relationalTabletGroup, - bool sorted); + static void buildInsertTabletReq(TSInsertTabletReq& request, Tablet& tablet, bool sorted); - void insertRelationalTablet(Tablet& tablet, bool sorted); + void insertTablet(TSInsertTabletReq request); - static void buildInsertTabletReq(TSInsertTabletReq& request, Tablet& tablet, bool sorted); + void insertAlignedTablet(Tablet& tablet); - void insertTablet(TSInsertTabletReq request); + void insertAlignedTablet(Tablet& tablet, bool sorted); - void insertAlignedTablet(Tablet& tablet); + void insertTablets(std::unordered_map& tablets); - void insertAlignedTablet(Tablet& tablet, bool sorted); + void insertTablets(std::unordered_map& tablets, bool sorted); - void insertTablets(std::unordered_map& tablets); + void insertAlignedTablets(std::unordered_map& tablets, bool sorted = false); - void insertTablets(std::unordered_map& tablets, bool sorted); + void testInsertRecord(const std::string& deviceId, int64_t time, + const std::vector& measurements, + const std::vector& values); - void insertAlignedTablets(std::unordered_map& tablets, bool sorted = false); + void testInsertTablet(const Tablet& tablet); - void testInsertRecord(const std::string& deviceId, int64_t time, - const std::vector& measurements, - const std::vector& values); + void testInsertRecords(const std::vector& deviceIds, + const std::vector& times, + const std::vector>& measurementsList, + const std::vector>& valuesList); - void testInsertTablet(const Tablet& tablet); + void deleteTimeseries(const std::string& path); - void testInsertRecords(const std::vector& deviceIds, - const std::vector& times, - const std::vector>& measurementsList, - const std::vector>& valuesList); + void deleteTimeseries(const std::vector& paths); - void deleteTimeseries(const std::string& path); + void deleteData(const std::string& path, int64_t endTime); - void deleteTimeseries(const std::vector& paths); + void deleteData(const std::vector& paths, int64_t endTime); - void deleteData(const std::string& path, int64_t endTime); + void deleteData(const std::vector& paths, int64_t startTime, int64_t endTime); - void deleteData(const std::vector& paths, int64_t endTime); + void setStorageGroup(const std::string& storageGroupId); - void deleteData(const std::vector& paths, int64_t startTime, int64_t endTime); + void deleteStorageGroup(const std::string& storageGroup); - void setStorageGroup(const std::string& storageGroupId); + void deleteStorageGroups(const std::vector& storageGroups); - void deleteStorageGroup(const std::string& storageGroup); + void createDatabase(const std::string& database); - void deleteStorageGroups(const std::vector& storageGroups); + void deleteDatabase(const std::string& database); - void createDatabase(const std::string& database); + void deleteDatabases(const std::vector& databases); - void deleteDatabase(const std::string& database); + void createTimeseries(const std::string& path, TSDataType::TSDataType dataType, + TSEncoding::TSEncoding encoding, + CompressionType::CompressionType compressor); - void deleteDatabases(const std::vector& databases); + void createTimeseries(const std::string& path, TSDataType::TSDataType dataType, + TSEncoding::TSEncoding encoding, + CompressionType::CompressionType compressor, + std::map* props, + std::map* tags, + std::map* attributes, + const std::string& measurementAlias); - void createTimeseries(const std::string& path, TSDataType::TSDataType dataType, TSEncoding::TSEncoding encoding, - CompressionType::CompressionType compressor); + void createMultiTimeseries(const std::vector& paths, + const std::vector& dataTypes, + const std::vector& encodings, + const std::vector& compressors, + std::vector>* propsList, + std::vector>* tagsList, + std::vector>* attributesList, + std::vector* measurementAliasList); - void createTimeseries(const std::string& path, TSDataType::TSDataType dataType, TSEncoding::TSEncoding encoding, - CompressionType::CompressionType compressor, - std::map* props, std::map* tags, - std::map* attributes, - const std::string& measurementAlias); - - void createMultiTimeseries(const std::vector& paths, + void createAlignedTimeseries(const std::string& deviceId, + const std::vector& measurements, const std::vector& dataTypes, const std::vector& encodings, - const std::vector& compressors, - std::vector>* propsList, - std::vector>* tagsList, - std::vector>* attributesList, - std::vector* measurementAliasList); + const std::vector& compressors); + + bool checkTimeseriesExists(const std::string& path); - void createAlignedTimeseries(const std::string& deviceId, - const std::vector& measurements, - const std::vector& dataTypes, - const std::vector& encodings, - const std::vector& compressors); + std::unique_ptr executeQueryStatement(const std::string& sql); - bool checkTimeseriesExists(const std::string& path); + std::unique_ptr executeQueryStatement(const std::string& sql, + int64_t timeoutInMs); - std::unique_ptr executeQueryStatement(const std::string& sql); + std::unique_ptr executeQueryStatementMayRedirect(const std::string& sql, + int64_t timeoutInMs); - std::unique_ptr executeQueryStatement(const std::string& sql, int64_t timeoutInMs); + void executeNonQueryStatement(const std::string& sql); - std::unique_ptr executeQueryStatementMayRedirect(const std::string& sql, int64_t timeoutInMs); + std::unique_ptr executeRawDataQuery(const std::vector& paths, + int64_t startTime, int64_t endTime); - void executeNonQueryStatement(const std::string& sql); + std::unique_ptr executeLastDataQuery(const std::vector& paths); - std::unique_ptr executeRawDataQuery(const std::vector& paths, int64_t startTime, - int64_t endTime); + std::unique_ptr executeLastDataQuery(const std::vector& paths, + int64_t lastTime); - std::unique_ptr executeLastDataQuery(const std::vector& paths); + void createSchemaTemplate(const Template& templ); - std::unique_ptr executeLastDataQuery(const std::vector& paths, int64_t lastTime); + void setSchemaTemplate(const std::string& template_name, const std::string& prefix_path); - void createSchemaTemplate(const Template& templ); + void unsetSchemaTemplate(const std::string& prefix_path, const std::string& template_name); - void setSchemaTemplate(const std::string& template_name, const std::string& prefix_path); + void addAlignedMeasurementsInTemplate( + const std::string& template_name, const std::vector& measurements, + const std::vector& dataTypes, + const std::vector& encodings, + const std::vector& compressors); - void unsetSchemaTemplate(const std::string& prefix_path, const std::string& template_name); + void addAlignedMeasurementsInTemplate(const std::string& template_name, + const std::string& measurement, + TSDataType::TSDataType dataType, + TSEncoding::TSEncoding encoding, + CompressionType::CompressionType compressor); - void addAlignedMeasurementsInTemplate(const std::string& template_name, - const std::vector& measurements, - const std::vector& dataTypes, - const std::vector& encodings, - const std::vector& compressors); + void addUnalignedMeasurementsInTemplate( + const std::string& template_name, const std::vector& measurements, + const std::vector& dataTypes, + const std::vector& encodings, + const std::vector& compressors); - void addAlignedMeasurementsInTemplate(const std::string& template_name, + void addUnalignedMeasurementsInTemplate(const std::string& template_name, const std::string& measurement, TSDataType::TSDataType dataType, TSEncoding::TSEncoding encoding, CompressionType::CompressionType compressor); - void addUnalignedMeasurementsInTemplate(const std::string& template_name, - const std::vector& measurements, - const std::vector& dataTypes, - const std::vector& encodings, - const std::vector& compressors); - - void addUnalignedMeasurementsInTemplate(const std::string& template_name, - const std::string& measurement, - TSDataType::TSDataType dataType, - TSEncoding::TSEncoding encoding, - CompressionType::CompressionType compressor); + void deleteNodeInTemplate(const std::string& template_name, const std::string& path); - void deleteNodeInTemplate(const std::string& template_name, const std::string& path); + int countMeasurementsInTemplate(const std::string& template_name); - int countMeasurementsInTemplate(const std::string& template_name); + bool isMeasurementInTemplate(const std::string& template_name, const std::string& path); - bool isMeasurementInTemplate(const std::string& template_name, const std::string& path); + bool isPathExistInTemplate(const std::string& template_name, const std::string& path); - bool isPathExistInTemplate(const std::string& template_name, const std::string& path); + std::vector showMeasurementsInTemplate(const std::string& template_name); - std::vector showMeasurementsInTemplate(const std::string& template_name); + std::vector showMeasurementsInTemplate(const std::string& template_name, + const std::string& pattern); - std::vector showMeasurementsInTemplate(const std::string& template_name, const std::string& pattern); - - bool checkTemplateExists(const std::string& template_name); + bool checkTemplateExists(const std::string& template_name); }; template void Session::insertByGroup(std::unordered_map, T>& insertGroup, InsertConsumer insertConsumer) { - std::vector> futures; - - for (auto& entry : insertGroup) { - auto connection = entry.first; - auto& req = entry.second; - futures.emplace_back(std::async(std::launch::async, [=, &req]() mutable { - try { - insertConsumer(connection, req); - } - catch (const RedirectException& e) { - for (const auto& deviceEndPoint : e.deviceEndPointMap) { - handleRedirection(deviceEndPoint.first, deviceEndPoint.second); - } - } catch (const IoTDBConnectionException& e) { - if (endPointToSessionConnection.size() > 1) { - removeBrokenSessionConnection(connection); - try { - insertConsumer(defaultSessionConnection_, req); - } - catch (const RedirectException&) { - } - } - else { - throw; - } - } catch (const std::exception& e) { - log_debug(e.what()); - throw IoTDBException(e.what()); - } - })); - } + std::vector> futures; - std::string errorMessages; - for (auto& f : futures) { - try { - f.get(); + for (auto& entry : insertGroup) { + auto connection = entry.first; + auto& req = entry.second; + futures.emplace_back(std::async(std::launch::async, [=, &req]() mutable { + try { + insertConsumer(connection, req); + } catch (const RedirectException& e) { + for (const auto& deviceEndPoint : e.deviceEndPointMap) { + handleRedirection(deviceEndPoint.first, deviceEndPoint.second); } - catch (const IoTDBConnectionException& e) { - throw; - } catch (const std::exception& e) { - if (!errorMessages.empty()) { - errorMessages += ";"; - } - errorMessages += e.what(); + } catch (const IoTDBConnectionException& e) { + if (endPointToSessionConnection.size() > 1) { + removeBrokenSessionConnection(connection); + try { + insertConsumer(defaultSessionConnection_, req); + } catch (const RedirectException&) { + } + } else { + throw; } + } catch (const std::exception& e) { + log_debug(e.what()); + throw IoTDBException(e.what()); + } + })); + } + + std::string errorMessages; + for (auto& f : futures) { + try { + f.get(); + } catch (const IoTDBConnectionException& e) { + throw; + } catch (const std::exception& e) { + if (!errorMessages.empty()) { + errorMessages += ";"; + } + errorMessages += e.what(); } + } - if (!errorMessages.empty()) { - throw StatementExecutionException(errorMessages); - } + if (!errorMessages.empty()) { + throw StatementExecutionException(errorMessages); + } } template void Session::insertOnce(std::unordered_map, T>& insertGroup, InsertConsumer insertConsumer) { - auto connection = insertGroup.begin()->first; - auto req = insertGroup.begin()->second; - try { - insertConsumer(connection, req); + auto connection = insertGroup.begin()->first; + auto req = insertGroup.begin()->second; + try { + insertConsumer(connection, req); + } catch (RedirectException e) { + for (const auto& deviceEndPoint : e.deviceEndPointMap) { + handleRedirection(deviceEndPoint.first, deviceEndPoint.second); } - catch (RedirectException e) { - for (const auto& deviceEndPoint : e.deviceEndPointMap) { - handleRedirection(deviceEndPoint.first, deviceEndPoint.second); - } - } catch (IoTDBConnectionException e) { - if (endPointToSessionConnection.size() > 1) { - removeBrokenSessionConnection(connection); - try { - insertConsumer(defaultSessionConnection_, req); - } - catch (RedirectException e) { - } - } - else { - throw e; - } + } catch (IoTDBConnectionException e) { + if (endPointToSessionConnection.size() > 1) { + removeBrokenSessionConnection(connection); + try { + insertConsumer(defaultSessionConnection_, req); + } catch (RedirectException e) { + } + } else { + throw e; } + } } #endif // IOTDB_SESSION_H diff --git a/iotdb-client/client-cpp/src/main/SessionBuilder.h b/iotdb-client/client-cpp/src/main/SessionBuilder.h index 02d31042491d9..14342697eb5d9 100644 --- a/iotdb-client/client-cpp/src/main/SessionBuilder.h +++ b/iotdb-client/client-cpp/src/main/SessionBuilder.h @@ -24,82 +24,83 @@ class SessionBuilder : public AbstractSessionBuilder { public: - SessionBuilder* host(const std::string &host) { - AbstractSessionBuilder::host = host; - return this; + SessionBuilder* host(const std::string& host) { + AbstractSessionBuilder::host = host; + return this; + } + + SessionBuilder* rpcPort(int rpcPort) { + AbstractSessionBuilder::rpcPort = rpcPort; + return this; + } + + SessionBuilder* useSSL(bool useSSL) { + AbstractSessionBuilder::useSSL = useSSL; + return this; + } + + SessionBuilder* trustCertFilePath(const std::string& trustCertFilePath) { + AbstractSessionBuilder::trustCertFilePath = trustCertFilePath; + return this; + } + + SessionBuilder* username(const std::string& username) { + AbstractSessionBuilder::username = username; + return this; + } + + SessionBuilder* password(const std::string& password) { + AbstractSessionBuilder::password = password; + return this; + } + + SessionBuilder* zoneId(const std::string& zoneId) { + AbstractSessionBuilder::zoneId = zoneId; + return this; + } + + SessionBuilder* fetchSize(int fetchSize) { + AbstractSessionBuilder::fetchSize = fetchSize; + return this; + } + + SessionBuilder* database(const std::string& database) { + AbstractSessionBuilder::database = database; + return this; + } + + SessionBuilder* nodeUrls(const std::vector& nodeUrls) { + AbstractSessionBuilder::nodeUrls = nodeUrls; + return this; + } + + SessionBuilder* enableAutoFetch(bool enableAutoFetch) { + AbstractSessionBuilder::enableAutoFetch = enableAutoFetch; + return this; + } + + SessionBuilder* enableRedirections(bool enableRedirections) { + AbstractSessionBuilder::enableRedirections = enableRedirections; + return this; + } + + SessionBuilder* enableRPCCompression(bool enableRPCCompression) { + AbstractSessionBuilder::enableRPCCompression = enableRPCCompression; + return this; + } + + std::shared_ptr build() { + if (!AbstractSessionBuilder::nodeUrls.empty() && + (AbstractSessionBuilder::host != DEFAULT_HOST || + AbstractSessionBuilder::rpcPort != DEFAULT_RPC_PORT)) { + throw IoTDBException( + "Session builder does not support setting node urls and host/rpcPort at the same time."); } - - SessionBuilder* rpcPort(int rpcPort) { - AbstractSessionBuilder::rpcPort = rpcPort; - return this; - } - - SessionBuilder* useSSL(bool useSSL) { - AbstractSessionBuilder::useSSL = useSSL; - return this; - } - - SessionBuilder* trustCertFilePath(const std::string &trustCertFilePath) { - AbstractSessionBuilder::trustCertFilePath = trustCertFilePath; - return this; - } - - SessionBuilder* username(const std::string &username) { - AbstractSessionBuilder::username = username; - return this; - } - - SessionBuilder* password(const std::string &password) { - AbstractSessionBuilder::password = password; - return this; - } - - SessionBuilder* zoneId(const std::string &zoneId) { - AbstractSessionBuilder::zoneId = zoneId; - return this; - } - - SessionBuilder* fetchSize(int fetchSize) { - AbstractSessionBuilder::fetchSize = fetchSize; - return this; - } - - SessionBuilder* database(const std::string &database) { - AbstractSessionBuilder::database = database; - return this; - } - - SessionBuilder* nodeUrls(const std::vector& nodeUrls) { - AbstractSessionBuilder::nodeUrls = nodeUrls; - return this; - } - - SessionBuilder* enableAutoFetch(bool enableAutoFetch) { - AbstractSessionBuilder::enableAutoFetch = enableAutoFetch; - return this; - } - - SessionBuilder* enableRedirections(bool enableRedirections) { - AbstractSessionBuilder::enableRedirections = enableRedirections; - return this; - } - - SessionBuilder* enableRPCCompression(bool enableRPCCompression) { - AbstractSessionBuilder::enableRPCCompression = enableRPCCompression; - return this; - } - - std::shared_ptr build() { - if (!AbstractSessionBuilder::nodeUrls.empty() && - (AbstractSessionBuilder::host != DEFAULT_HOST || - AbstractSessionBuilder::rpcPort != DEFAULT_RPC_PORT)) { - throw IoTDBException("Session builder does not support setting node urls and host/rpcPort at the same time."); - } - sqlDialect = "tree"; - auto newSession = std::make_shared(this); - newSession->open(false); - return newSession; - } + sqlDialect = "tree"; + auto newSession = std::make_shared(this); + newSession->open(false); + return newSession; + } }; #endif // IOTDB_SESSION_BUILDER_H \ No newline at end of file diff --git a/iotdb-client/client-cpp/src/main/SessionC.cpp b/iotdb-client/client-cpp/src/main/SessionC.cpp index 15d0deaec56de..e7c43cdb9f1be 100644 --- a/iotdb-client/client-cpp/src/main/SessionC.cpp +++ b/iotdb-client/client-cpp/src/main/SessionC.cpp @@ -36,23 +36,23 @@ * ============================================================ */ struct CSession_ { - std::shared_ptr cpp; + std::shared_ptr cpp; }; struct CTableSession_ { - std::shared_ptr cpp; + std::shared_ptr cpp; }; struct CTablet_ { - Tablet cpp; + Tablet cpp; }; struct CSessionDataSet_ { - std::unique_ptr cpp; + std::unique_ptr cpp; }; struct CRowRecord_ { - std::shared_ptr cpp; + std::shared_ptr cpp; }; /* ============================================================ @@ -62,88 +62,90 @@ struct CRowRecord_ { static thread_local std::string g_lastError; static void clearError() { - g_lastError.clear(); + g_lastError.clear(); } static TsStatus setError(TsStatus code, const std::string& msg) { - g_lastError = msg; - return code; + g_lastError = msg; + return code; } static TsStatus setError(TsStatus code, const std::exception& e) { - g_lastError = e.what(); - return code; + g_lastError = e.what(); + return code; } static TsStatus handleException(const std::exception& e) { #if defined(_CPPRTTI) || defined(__GXX_RTTI) - // Try to classify exception type (requires RTTI enabled). - if (dynamic_cast(&e)) { - return setError(TS_ERR_CONNECTION, e); - } - if (dynamic_cast(&e) || - dynamic_cast(&e) || - dynamic_cast(&e)) { - return setError(TS_ERR_EXECUTION, e); - } + // Try to classify exception type (requires RTTI enabled). + if (dynamic_cast(&e)) { + return setError(TS_ERR_CONNECTION, e); + } + if (dynamic_cast(&e) || + dynamic_cast(&e) || + dynamic_cast(&e)) { + return setError(TS_ERR_EXECUTION, e); + } #endif - return setError(TS_ERR_UNKNOWN, e); + return setError(TS_ERR_UNKNOWN, e); } extern "C" { const char* ts_get_last_error(void) { - return g_lastError.c_str(); + return g_lastError.c_str(); } -} /* extern "C" */ +} /* extern "C" */ /* ============================================================ * Helpers — convert C arrays to C++ vectors * ============================================================ */ static std::vector toStringVec(const char* const* arr, int count) { - std::vector v; - v.reserve(count); - for (int i = 0; i < count; i++) { - v.emplace_back(arr[i]); - } - return v; + std::vector v; + v.reserve(count); + for (int i = 0; i < count; i++) { + v.emplace_back(arr[i]); + } + return v; } static std::vector toTypeVec(const TSDataType_C* arr, int count) { - std::vector v; - v.reserve(count); - for (int i = 0; i < count; i++) { - v.push_back(static_cast(arr[i])); - } - return v; + std::vector v; + v.reserve(count); + for (int i = 0; i < count; i++) { + v.push_back(static_cast(arr[i])); + } + return v; } static std::vector toEncodingVec(const TSEncoding_C* arr, int count) { - std::vector v; - v.reserve(count); - for (int i = 0; i < count; i++) { - v.push_back(static_cast(arr[i])); - } - return v; + std::vector v; + v.reserve(count); + for (int i = 0; i < count; i++) { + v.push_back(static_cast(arr[i])); + } + return v; } -static std::vector toCompressionVec(const TSCompressionType_C* arr, int count) { - std::vector v; - v.reserve(count); - for (int i = 0; i < count; i++) { - v.push_back(static_cast(arr[i])); - } - return v; +static std::vector +toCompressionVec(const TSCompressionType_C* arr, int count) { + std::vector v; + v.reserve(count); + for (int i = 0; i < count; i++) { + v.push_back(static_cast(arr[i])); + } + return v; } -static std::map toStringMap(int count, const char* const* keys, const char* const* values) { - std::map m; - for (int i = 0; i < count; i++) { - m[keys[i]] = values[i]; - } - return m; +static std::map toStringMap(int count, const char* const* keys, + const char* const* values) { + std::map m; + for (int i = 0; i < count; i++) { + m[keys[i]] = values[i]; + } + return m; } /** @@ -151,64 +153,77 @@ static std::map toStringMap(int count, const char* con * to C++ vector that Session expects. * The caller must free the returned char* pointers using freeCharPtrVec(). */ -static std::vector toCharPtrVec(const TSDataType_C* types, const void* const* values, int count) { - std::vector result(count); - for (int i = 0; i < count; i++) { - switch (types[i]) { - case TS_TYPE_BOOLEAN: { - bool* p = new bool(*static_cast(values[i])); - result[i] = reinterpret_cast(p); - break; - } - case TS_TYPE_INT32: { - int32_t* p = new int32_t(*static_cast(values[i])); - result[i] = reinterpret_cast(p); - break; - } - case TS_TYPE_INT64: - case TS_TYPE_TIMESTAMP: { - int64_t* p = new int64_t(*static_cast(values[i])); - result[i] = reinterpret_cast(p); - break; - } - case TS_TYPE_FLOAT: { - float* p = new float(*static_cast(values[i])); - result[i] = reinterpret_cast(p); - break; - } - case TS_TYPE_DOUBLE: { - double* p = new double(*static_cast(values[i])); - result[i] = reinterpret_cast(p); - break; - } - case TS_TYPE_TEXT: - case TS_TYPE_STRING: - case TS_TYPE_BLOB: - default: { - const char* src = static_cast(values[i]); - size_t len = strlen(src) + 1; - char* p = new char[len]; - memcpy(p, src, len); - result[i] = p; - break; - } - } - } - return result; +static std::vector toCharPtrVec(const TSDataType_C* types, const void* const* values, + int count) { + std::vector result(count); + for (int i = 0; i < count; i++) { + switch (types[i]) { + case TS_TYPE_BOOLEAN: { + bool* p = new bool(*static_cast(values[i])); + result[i] = reinterpret_cast(p); + break; + } + case TS_TYPE_INT32: { + int32_t* p = new int32_t(*static_cast(values[i])); + result[i] = reinterpret_cast(p); + break; + } + case TS_TYPE_INT64: + case TS_TYPE_TIMESTAMP: { + int64_t* p = new int64_t(*static_cast(values[i])); + result[i] = reinterpret_cast(p); + break; + } + case TS_TYPE_FLOAT: { + float* p = new float(*static_cast(values[i])); + result[i] = reinterpret_cast(p); + break; + } + case TS_TYPE_DOUBLE: { + double* p = new double(*static_cast(values[i])); + result[i] = reinterpret_cast(p); + break; + } + case TS_TYPE_TEXT: + case TS_TYPE_STRING: + case TS_TYPE_BLOB: + default: { + const char* src = static_cast(values[i]); + size_t len = strlen(src) + 1; + char* p = new char[len]; + memcpy(p, src, len); + result[i] = p; + break; + } + } + } + return result; } static void freeCharPtrVec(std::vector& vec, const TSDataType_C* types, int count) { - for (int i = 0; i < count; i++) { - switch (types[i]) { - case TS_TYPE_BOOLEAN: delete reinterpret_cast(vec[i]); break; - case TS_TYPE_INT32: delete reinterpret_cast(vec[i]); break; - case TS_TYPE_INT64: - case TS_TYPE_TIMESTAMP: delete reinterpret_cast(vec[i]); break; - case TS_TYPE_FLOAT: delete reinterpret_cast(vec[i]); break; - case TS_TYPE_DOUBLE: delete reinterpret_cast(vec[i]); break; - default: delete[] vec[i]; break; - } - } + for (int i = 0; i < count; i++) { + switch (types[i]) { + case TS_TYPE_BOOLEAN: + delete reinterpret_cast(vec[i]); + break; + case TS_TYPE_INT32: + delete reinterpret_cast(vec[i]); + break; + case TS_TYPE_INT64: + case TS_TYPE_TIMESTAMP: + delete reinterpret_cast(vec[i]); + break; + case TS_TYPE_FLOAT: + delete reinterpret_cast(vec[i]); + break; + case TS_TYPE_DOUBLE: + delete reinterpret_cast(vec[i]); + break; + default: + delete[] vec[i]; + break; + } + } } /* ============================================================ @@ -217,166 +232,166 @@ static void freeCharPtrVec(std::vector& vec, const TSDataType_C* types, i extern "C" { -CSession* ts_session_new(const char* host, int rpcPort, - const char* username, const char* password) { - clearError(); - try { - auto cpp = std::make_shared( - std::string(host), rpcPort, - std::string(username), std::string(password)); - auto* cs = new CSession_(); - cs->cpp = std::move(cpp); - return cs; - } catch (const std::exception& e) { - handleException(e); - return nullptr; - } -} - -CSession* ts_session_new_with_zone(const char* host, int rpcPort, - const char* username, const char* password, - const char* zoneId, int fetchSize) { - clearError(); - try { - auto cpp = std::make_shared( - std::string(host), rpcPort, - std::string(username), std::string(password), - std::string(zoneId), fetchSize); - auto* cs = new CSession_(); - cs->cpp = std::move(cpp); - return cs; - } catch (const std::exception& e) { - handleException(e); - return nullptr; - } -} - -CSession* ts_session_new_multi_node(const char* const* nodeUrls, int urlCount, - const char* username, const char* password) { - clearError(); - try { - auto urls = toStringVec(nodeUrls, urlCount); - auto cpp = std::make_shared(urls, std::string(username), std::string(password)); - auto* cs = new CSession_(); - cs->cpp = std::move(cpp); - return cs; - } catch (const std::exception& e) { - handleException(e); - return nullptr; - } +CSession* ts_session_new(const char* host, int rpcPort, const char* username, + const char* password) { + clearError(); + try { + auto cpp = std::make_shared(std::string(host), rpcPort, std::string(username), + std::string(password)); + auto* cs = new CSession_(); + cs->cpp = std::move(cpp); + return cs; + } catch (const std::exception& e) { + handleException(e); + return nullptr; + } +} + +CSession* ts_session_new_with_zone(const char* host, int rpcPort, const char* username, + const char* password, const char* zoneId, int fetchSize) { + clearError(); + try { + auto cpp = std::make_shared(std::string(host), rpcPort, std::string(username), + std::string(password), std::string(zoneId), fetchSize); + auto* cs = new CSession_(); + cs->cpp = std::move(cpp); + return cs; + } catch (const std::exception& e) { + handleException(e); + return nullptr; + } +} + +CSession* ts_session_new_multi_node(const char* const* nodeUrls, int urlCount, const char* username, + const char* password) { + clearError(); + try { + auto urls = toStringVec(nodeUrls, urlCount); + auto cpp = std::make_shared(urls, std::string(username), std::string(password)); + auto* cs = new CSession_(); + cs->cpp = std::move(cpp); + return cs; + } catch (const std::exception& e) { + handleException(e); + return nullptr; + } } void ts_session_destroy(CSession* session) { - delete session; + delete session; } TsStatus ts_session_open(CSession* session) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->open(); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->open(); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_session_open_with_compression(CSession* session, bool enableRPCCompression) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->open(enableRPCCompression); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->open(enableRPCCompression); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_session_close(CSession* session) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->close(); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->close(); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ * Session Lifecycle — Table Model * ============================================================ */ -CTableSession* ts_table_session_new(const char* host, int rpcPort, - const char* username, const char* password, - const char* database) { - clearError(); - try { - std::unique_ptr builder(new TableSessionBuilder()); - auto tableSession = builder->host(std::string(host)) - ->rpcPort(rpcPort) - ->username(std::string(username)) - ->password(std::string(password)) - ->database(std::string(database ? database : "")) - ->build(); - CTableSession_ tmp{}; - tmp.cpp = std::move(tableSession); - auto* cts = new CTableSession_(); - cts->cpp = std::move(tmp.cpp); - return cts; - } catch (const std::exception& e) { - handleException(e); - return nullptr; - } +CTableSession* ts_table_session_new(const char* host, int rpcPort, const char* username, + const char* password, const char* database) { + clearError(); + try { + std::unique_ptr builder(new TableSessionBuilder()); + auto tableSession = builder->host(std::string(host)) + ->rpcPort(rpcPort) + ->username(std::string(username)) + ->password(std::string(password)) + ->database(std::string(database ? database : "")) + ->build(); + CTableSession_ tmp{}; + tmp.cpp = std::move(tableSession); + auto* cts = new CTableSession_(); + cts->cpp = std::move(tmp.cpp); + return cts; + } catch (const std::exception& e) { + handleException(e); + return nullptr; + } } CTableSession* ts_table_session_new_multi_node(const char* const* nodeUrls, int urlCount, - const char* username, const char* password, - const char* database) { - clearError(); - try { - auto urls = toStringVec(nodeUrls, urlCount); - std::unique_ptr builder(new TableSessionBuilder()); - auto tableSession = builder->nodeUrls(urls) - ->username(std::string(username)) - ->password(std::string(password)) - ->database(std::string(database ? database : "")) - ->build(); - CTableSession_ tmp{}; - tmp.cpp = std::move(tableSession); - auto* cts = new CTableSession_(); - cts->cpp = std::move(tmp.cpp); - return cts; - } catch (const std::exception& e) { - handleException(e); - return nullptr; - } + const char* username, const char* password, + const char* database) { + clearError(); + try { + auto urls = toStringVec(nodeUrls, urlCount); + std::unique_ptr builder(new TableSessionBuilder()); + auto tableSession = builder->nodeUrls(urls) + ->username(std::string(username)) + ->password(std::string(password)) + ->database(std::string(database ? database : "")) + ->build(); + CTableSession_ tmp{}; + tmp.cpp = std::move(tableSession); + auto* cts = new CTableSession_(); + cts->cpp = std::move(tmp.cpp); + return cts; + } catch (const std::exception& e) { + handleException(e); + return nullptr; + } } void ts_table_session_destroy(CTableSession* session) { - delete session; + delete session; } TsStatus ts_table_session_open(CTableSession* session) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->open(); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->open(); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_table_session_close(CTableSession* session) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->close(); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->close(); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ @@ -384,31 +399,34 @@ TsStatus ts_table_session_close(CTableSession* session) { * ============================================================ */ TsStatus ts_session_set_timezone(CSession* session, const char* zoneId) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->setTimeZone(std::string(zoneId)); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->setTimeZone(std::string(zoneId)); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_session_get_timezone(CSession* session, char* buf, int bufLen) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!buf || bufLen <= 0) return setError(TS_ERR_INVALID_PARAM, "invalid buffer"); - try { - std::string tz = session->cpp->getTimeZone(); - if ((int)tz.size() >= bufLen) { - return setError(TS_ERR_INVALID_PARAM, "buffer too small"); - } - strncpy(buf, tz.c_str(), bufLen); - buf[bufLen - 1] = '\0'; - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!buf || bufLen <= 0) + return setError(TS_ERR_INVALID_PARAM, "invalid buffer"); + try { + std::string tz = session->cpp->getTimeZone(); + if ((int)tz.size() >= bufLen) { + return setError(TS_ERR_INVALID_PARAM, "buffer too small"); + } + strncpy(buf, tz.c_str(), bufLen); + buf[bufLen - 1] = '\0'; + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ @@ -416,391 +434,401 @@ TsStatus ts_session_get_timezone(CSession* session, char* buf, int bufLen) { * ============================================================ */ TsStatus ts_session_create_database(CSession* session, const char* database) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->createDatabase(std::string(database)); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->createDatabase(std::string(database)); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_session_delete_database(CSession* session, const char* database) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->deleteDatabase(std::string(database)); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->deleteDatabase(std::string(database)); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_session_delete_databases(CSession* session, const char* const* databases, int count) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto dbs = toStringVec(databases, count); - session->cpp->deleteDatabases(dbs); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto dbs = toStringVec(databases, count); + session->cpp->deleteDatabases(dbs); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ * Timeseries Management (Tree Model) * ============================================================ */ -TsStatus ts_session_create_timeseries(CSession* session, const char* path, - TSDataType_C dataType, TSEncoding_C encoding, - TSCompressionType_C compressor) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->createTimeseries( - std::string(path), - static_cast(dataType), - static_cast(encoding), - static_cast(compressor)); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_session_create_timeseries_ex(CSession* session, const char* path, - TSDataType_C dataType, TSEncoding_C encoding, - TSCompressionType_C compressor, - int propsCount, - const char* const* propKeys, - const char* const* propValues, - int tagsCount, - const char* const* tagKeys, - const char* const* tagValues, - int attrsCount, - const char* const* attrKeys, - const char* const* attrValues, - const char* measurementAlias) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - std::map props = propsCount > 0 ? toStringMap(propsCount, propKeys, propValues) : std::map(); - std::map tags = tagsCount > 0 ? toStringMap(tagsCount, tagKeys, tagValues) : std::map(); - std::map attrs = attrsCount > 0 ? toStringMap(attrsCount, attrKeys, attrValues) : std::map(); - session->cpp->createTimeseries( - std::string(path), - static_cast(dataType), - static_cast(encoding), - static_cast(compressor), - &props, &tags, &attrs, - std::string(measurementAlias ? measurementAlias : "")); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_session_create_multi_timeseries(CSession* session, int count, - const char* const* paths, - const TSDataType_C* dataTypes, - const TSEncoding_C* encodings, - const TSCompressionType_C* compressors) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto pathsVec = toStringVec(paths, count); - auto typesVec = toTypeVec(dataTypes, count); - auto encVec = toEncodingVec(encodings, count); - auto compVec = toCompressionVec(compressors, count); - session->cpp->createMultiTimeseries( - pathsVec, typesVec, encVec, compVec, - nullptr, nullptr, nullptr, nullptr); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_session_create_aligned_timeseries(CSession* session, const char* deviceId, - int count, - const char* const* measurements, - const TSDataType_C* dataTypes, - const TSEncoding_C* encodings, - const TSCompressionType_C* compressors) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto measurementsVec = toStringVec(measurements, count); - auto typesVec = toTypeVec(dataTypes, count); - auto encVec = toEncodingVec(encodings, count); - auto compVec = toCompressionVec(compressors, count); - session->cpp->createAlignedTimeseries( - std::string(deviceId), measurementsVec, typesVec, encVec, compVec); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } +TsStatus ts_session_create_timeseries(CSession* session, const char* path, TSDataType_C dataType, + TSEncoding_C encoding, TSCompressionType_C compressor) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->createTimeseries(std::string(path), static_cast(dataType), + static_cast(encoding), + static_cast(compressor)); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_create_timeseries_ex(CSession* session, const char* path, TSDataType_C dataType, + TSEncoding_C encoding, TSCompressionType_C compressor, + int propsCount, const char* const* propKeys, + const char* const* propValues, int tagsCount, + const char* const* tagKeys, const char* const* tagValues, + int attrsCount, const char* const* attrKeys, + const char* const* attrValues, + const char* measurementAlias) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + std::map props = propsCount > 0 + ? toStringMap(propsCount, propKeys, propValues) + : std::map(); + std::map tags = tagsCount > 0 + ? toStringMap(tagsCount, tagKeys, tagValues) + : std::map(); + std::map attrs = attrsCount > 0 + ? toStringMap(attrsCount, attrKeys, attrValues) + : std::map(); + session->cpp->createTimeseries(std::string(path), static_cast(dataType), + static_cast(encoding), + static_cast(compressor), + &props, &tags, &attrs, + std::string(measurementAlias ? measurementAlias : "")); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_create_multi_timeseries(CSession* session, int count, const char* const* paths, + const TSDataType_C* dataTypes, + const TSEncoding_C* encodings, + const TSCompressionType_C* compressors) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto pathsVec = toStringVec(paths, count); + auto typesVec = toTypeVec(dataTypes, count); + auto encVec = toEncodingVec(encodings, count); + auto compVec = toCompressionVec(compressors, count); + session->cpp->createMultiTimeseries(pathsVec, typesVec, encVec, compVec, nullptr, nullptr, + nullptr, nullptr); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_create_aligned_timeseries(CSession* session, const char* deviceId, int count, + const char* const* measurements, + const TSDataType_C* dataTypes, + const TSEncoding_C* encodings, + const TSCompressionType_C* compressors) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto measurementsVec = toStringVec(measurements, count); + auto typesVec = toTypeVec(dataTypes, count); + auto encVec = toEncodingVec(encodings, count); + auto compVec = toCompressionVec(compressors, count); + session->cpp->createAlignedTimeseries(std::string(deviceId), measurementsVec, typesVec, encVec, + compVec); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_session_check_timeseries_exists(CSession* session, const char* path, bool* exists) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!exists) return setError(TS_ERR_INVALID_PARAM, "exists pointer is null"); - try { - *exists = session->cpp->checkTimeseriesExists(std::string(path)); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!exists) + return setError(TS_ERR_INVALID_PARAM, "exists pointer is null"); + try { + *exists = session->cpp->checkTimeseriesExists(std::string(path)); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_session_delete_timeseries(CSession* session, const char* path) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->deleteTimeseries(std::string(path)); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_session_delete_timeseries_batch(CSession* session, const char* const* paths, int count) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto pathsVec = toStringVec(paths, count); - session->cpp->deleteTimeseries(pathsVec); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->deleteTimeseries(std::string(path)); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_delete_timeseries_batch(CSession* session, const char* const* paths, + int count) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto pathsVec = toStringVec(paths, count); + session->cpp->deleteTimeseries(pathsVec); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ * Tablet Operations * ============================================================ */ -CTablet* ts_tablet_new(const char* deviceId, int columnCount, - const char* const* columnNames, - const TSDataType_C* dataTypes, - int maxRowNumber) { - try { - std::vector> schemas; - schemas.reserve(columnCount); - for (int i = 0; i < columnCount; i++) { - schemas.emplace_back(std::string(columnNames[i]), - static_cast(dataTypes[i])); - } - Tablet tablet(std::string(deviceId), schemas, maxRowNumber); - auto* ct = new CTablet_(); - ct->cpp = std::move(tablet); - return ct; - } catch (const std::exception& e) { - handleException(e); - return nullptr; - } +CTablet* ts_tablet_new(const char* deviceId, int columnCount, const char* const* columnNames, + const TSDataType_C* dataTypes, int maxRowNumber) { + try { + std::vector> schemas; + schemas.reserve(columnCount); + for (int i = 0; i < columnCount; i++) { + schemas.emplace_back(std::string(columnNames[i]), + static_cast(dataTypes[i])); + } + Tablet tablet(std::string(deviceId), schemas, maxRowNumber); + auto* ct = new CTablet_(); + ct->cpp = std::move(tablet); + return ct; + } catch (const std::exception& e) { + handleException(e); + return nullptr; + } } CTablet* ts_tablet_new_with_category(const char* deviceId, int columnCount, - const char* const* columnNames, - const TSDataType_C* dataTypes, - const TSColumnCategory_C* columnCategories, - int maxRowNumber) { - try { - std::vector> schemas; - std::vector colTypes; - schemas.reserve(columnCount); - colTypes.reserve(columnCount); - for (int i = 0; i < columnCount; i++) { - schemas.emplace_back(std::string(columnNames[i]), - static_cast(dataTypes[i])); - colTypes.push_back(static_cast(columnCategories[i])); - } - Tablet tablet(std::string(deviceId), schemas, colTypes, maxRowNumber); - auto* ct = new CTablet_(); - ct->cpp = std::move(tablet); - return ct; - } catch (const std::exception& e) { - handleException(e); - return nullptr; - } + const char* const* columnNames, const TSDataType_C* dataTypes, + const TSColumnCategory_C* columnCategories, int maxRowNumber) { + try { + std::vector> schemas; + std::vector colTypes; + schemas.reserve(columnCount); + colTypes.reserve(columnCount); + for (int i = 0; i < columnCount; i++) { + schemas.emplace_back(std::string(columnNames[i]), + static_cast(dataTypes[i])); + colTypes.push_back(static_cast(columnCategories[i])); + } + Tablet tablet(std::string(deviceId), schemas, colTypes, maxRowNumber); + auto* ct = new CTablet_(); + ct->cpp = std::move(tablet); + return ct; + } catch (const std::exception& e) { + handleException(e); + return nullptr; + } } void ts_tablet_destroy(CTablet* tablet) { - delete tablet; + delete tablet; } void ts_tablet_reset(CTablet* tablet) { - if (tablet) { - tablet->cpp.reset(); - } + if (tablet) { + tablet->cpp.reset(); + } } int ts_tablet_get_row_count(CTablet* tablet) { - if (!tablet) return 0; - return static_cast(tablet->cpp.rowSize); + if (!tablet) + return 0; + return static_cast(tablet->cpp.rowSize); } TsStatus ts_tablet_set_row_count(CTablet* tablet, int rowCount) { - clearError(); - if (!tablet) return setError(TS_ERR_NULL_PTR, "tablet is null"); - tablet->cpp.rowSize = rowCount; - return TS_OK; + clearError(); + if (!tablet) + return setError(TS_ERR_NULL_PTR, "tablet is null"); + tablet->cpp.rowSize = rowCount; + return TS_OK; } TsStatus ts_tablet_add_timestamp(CTablet* tablet, int rowIndex, int64_t timestamp) { - clearError(); - if (!tablet) return setError(TS_ERR_NULL_PTR, "tablet is null"); - try { - tablet->cpp.addTimestamp(static_cast(rowIndex), timestamp); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!tablet) + return setError(TS_ERR_NULL_PTR, "tablet is null"); + try { + tablet->cpp.addTimestamp(static_cast(rowIndex), timestamp); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_tablet_add_value_bool(CTablet* tablet, int colIndex, int rowIndex, bool value) { - clearError(); - if (!tablet) return setError(TS_ERR_NULL_PTR, "tablet is null"); - try { - tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), value); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!tablet) + return setError(TS_ERR_NULL_PTR, "tablet is null"); + try { + tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), value); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_tablet_add_value_int32(CTablet* tablet, int colIndex, int rowIndex, int32_t value) { - clearError(); - if (!tablet) return setError(TS_ERR_NULL_PTR, "tablet is null"); - try { - tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), value); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!tablet) + return setError(TS_ERR_NULL_PTR, "tablet is null"); + try { + tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), value); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_tablet_add_value_int64(CTablet* tablet, int colIndex, int rowIndex, int64_t value) { - clearError(); - if (!tablet) return setError(TS_ERR_NULL_PTR, "tablet is null"); - try { - tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), value); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!tablet) + return setError(TS_ERR_NULL_PTR, "tablet is null"); + try { + tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), value); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_tablet_add_value_float(CTablet* tablet, int colIndex, int rowIndex, float value) { - clearError(); - if (!tablet) return setError(TS_ERR_NULL_PTR, "tablet is null"); - try { - tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), value); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!tablet) + return setError(TS_ERR_NULL_PTR, "tablet is null"); + try { + tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), value); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_tablet_add_value_double(CTablet* tablet, int colIndex, int rowIndex, double value) { - clearError(); - if (!tablet) return setError(TS_ERR_NULL_PTR, "tablet is null"); - try { - tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), value); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_tablet_add_value_string(CTablet* tablet, int colIndex, int rowIndex, const char* value) { - clearError(); - if (!tablet) return setError(TS_ERR_NULL_PTR, "tablet is null"); - try { - std::string str(value); - tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), str); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!tablet) + return setError(TS_ERR_NULL_PTR, "tablet is null"); + try { + tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), value); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_tablet_add_value_string(CTablet* tablet, int colIndex, int rowIndex, + const char* value) { + clearError(); + if (!tablet) + return setError(TS_ERR_NULL_PTR, "tablet is null"); + try { + std::string str(value); + tablet->cpp.addValue(static_cast(colIndex), static_cast(rowIndex), str); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ * Data Insertion — Tree Model (Record, string values) * ============================================================ */ -TsStatus ts_session_insert_record_str(CSession* session, const char* deviceId, - int64_t time, int count, - const char* const* measurements, - const char* const* values) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto measurementsVec = toStringVec(measurements, count); - auto valuesVec = toStringVec(values, count); - session->cpp->insertRecord(std::string(deviceId), time, measurementsVec, valuesVec); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_session_insert_record(CSession* session, const char* deviceId, - int64_t time, int count, - const char* const* measurements, - const TSDataType_C* types, - const void* const* values) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto measurementsVec = toStringVec(measurements, count); - auto typesVec = toTypeVec(types, count); - auto charVec = toCharPtrVec(types, values, count); - session->cpp->insertRecord(std::string(deviceId), time, measurementsVec, typesVec, charVec); - freeCharPtrVec(charVec, types, count); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_session_insert_aligned_record_str(CSession* session, const char* deviceId, - int64_t time, int count, - const char* const* measurements, - const char* const* values) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto measurementsVec = toStringVec(measurements, count); - auto valuesVec = toStringVec(values, count); - session->cpp->insertAlignedRecord(std::string(deviceId), time, measurementsVec, valuesVec); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_session_insert_aligned_record(CSession* session, const char* deviceId, - int64_t time, int count, - const char* const* measurements, - const TSDataType_C* types, - const void* const* values) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto measurementsVec = toStringVec(measurements, count); - auto typesVec = toTypeVec(types, count); - auto charVec = toCharPtrVec(types, values, count); - session->cpp->insertAlignedRecord(std::string(deviceId), time, measurementsVec, typesVec, charVec); - freeCharPtrVec(charVec, types, count); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } +TsStatus ts_session_insert_record_str(CSession* session, const char* deviceId, int64_t time, + int count, const char* const* measurements, + const char* const* values) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto measurementsVec = toStringVec(measurements, count); + auto valuesVec = toStringVec(values, count); + session->cpp->insertRecord(std::string(deviceId), time, measurementsVec, valuesVec); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_insert_record(CSession* session, const char* deviceId, int64_t time, int count, + const char* const* measurements, const TSDataType_C* types, + const void* const* values) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto measurementsVec = toStringVec(measurements, count); + auto typesVec = toTypeVec(types, count); + auto charVec = toCharPtrVec(types, values, count); + session->cpp->insertRecord(std::string(deviceId), time, measurementsVec, typesVec, charVec); + freeCharPtrVec(charVec, types, count); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_insert_aligned_record_str(CSession* session, const char* deviceId, int64_t time, + int count, const char* const* measurements, + const char* const* values) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto measurementsVec = toStringVec(measurements, count); + auto valuesVec = toStringVec(values, count); + session->cpp->insertAlignedRecord(std::string(deviceId), time, measurementsVec, valuesVec); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_insert_aligned_record(CSession* session, const char* deviceId, int64_t time, + int count, const char* const* measurements, + const TSDataType_C* types, const void* const* values) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto measurementsVec = toStringVec(measurements, count); + auto typesVec = toTypeVec(types, count); + auto charVec = toCharPtrVec(types, values, count); + session->cpp->insertAlignedRecord(std::string(deviceId), time, measurementsVec, typesVec, + charVec); + freeCharPtrVec(charVec, types, count); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ @@ -808,191 +836,188 @@ TsStatus ts_session_insert_aligned_record(CSession* session, const char* deviceI * ============================================================ */ TsStatus ts_session_insert_records_str(CSession* session, int deviceCount, - const char* const* deviceIds, - const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const char* const* const* valuesList) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto devVec = toStringVec(deviceIds, deviceCount); - std::vector timesVec(times, times + deviceCount); - std::vector> mList, vList; - mList.reserve(deviceCount); - vList.reserve(deviceCount); - for (int i = 0; i < deviceCount; i++) { - mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); - vList.push_back(toStringVec(valuesList[i], measurementCounts[i])); - } - session->cpp->insertRecords(devVec, timesVec, mList, vList); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + const char* const* deviceIds, const int64_t* times, + const int* measurementCounts, + const char* const* const* measurementsList, + const char* const* const* valuesList) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto devVec = toStringVec(deviceIds, deviceCount); + std::vector timesVec(times, times + deviceCount); + std::vector> mList, vList; + mList.reserve(deviceCount); + vList.reserve(deviceCount); + for (int i = 0; i < deviceCount; i++) { + mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); + vList.push_back(toStringVec(valuesList[i], measurementCounts[i])); + } + session->cpp->insertRecords(devVec, timesVec, mList, vList); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_session_insert_aligned_records_str(CSession* session, int deviceCount, - const char* const* deviceIds, - const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const char* const* const* valuesList) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto devVec = toStringVec(deviceIds, deviceCount); - std::vector timesVec(times, times + deviceCount); - std::vector> mList, vList; - mList.reserve(deviceCount); - vList.reserve(deviceCount); - for (int i = 0; i < deviceCount; i++) { - mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); - vList.push_back(toStringVec(valuesList[i], measurementCounts[i])); - } - session->cpp->insertAlignedRecords(devVec, timesVec, mList, vList); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + const char* const* deviceIds, const int64_t* times, + const int* measurementCounts, + const char* const* const* measurementsList, + const char* const* const* valuesList) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto devVec = toStringVec(deviceIds, deviceCount); + std::vector timesVec(times, times + deviceCount); + std::vector> mList, vList; + mList.reserve(deviceCount); + vList.reserve(deviceCount); + for (int i = 0; i < deviceCount; i++) { + mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); + vList.push_back(toStringVec(valuesList[i], measurementCounts[i])); + } + session->cpp->insertAlignedRecords(devVec, timesVec, mList, vList); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ * Data Insertion — Batch, multiple devices (typed values) * ============================================================ */ -TsStatus ts_session_insert_records(CSession* session, int deviceCount, - const char* const* deviceIds, - const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const TSDataType_C* const* typesList, - const void* const* const* valuesList) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto devVec = toStringVec(deviceIds, deviceCount); - std::vector timesVec(times, times + deviceCount); - std::vector> mList; - std::vector> tList; - std::vector> vList; - mList.reserve(deviceCount); - tList.reserve(deviceCount); - vList.reserve(deviceCount); - for (int i = 0; i < deviceCount; i++) { - mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); - tList.push_back(toTypeVec(typesList[i], measurementCounts[i])); - vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i])); - } - session->cpp->insertRecords(devVec, timesVec, mList, tList, vList); - for (int i = 0; i < deviceCount; i++) { - freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]); - } - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); +TsStatus ts_session_insert_records(CSession* session, int deviceCount, const char* const* deviceIds, + const int64_t* times, const int* measurementCounts, + const char* const* const* measurementsList, + const TSDataType_C* const* typesList, + const void* const* const* valuesList) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto devVec = toStringVec(deviceIds, deviceCount); + std::vector timesVec(times, times + deviceCount); + std::vector> mList; + std::vector> tList; + std::vector> vList; + mList.reserve(deviceCount); + tList.reserve(deviceCount); + vList.reserve(deviceCount); + for (int i = 0; i < deviceCount; i++) { + mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); + tList.push_back(toTypeVec(typesList[i], measurementCounts[i])); + vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i])); + } + session->cpp->insertRecords(devVec, timesVec, mList, tList, vList); + for (int i = 0; i < deviceCount; i++) { + freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]); } + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_session_insert_aligned_records(CSession* session, int deviceCount, - const char* const* deviceIds, - const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const TSDataType_C* const* typesList, - const void* const* const* valuesList) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto devVec = toStringVec(deviceIds, deviceCount); - std::vector timesVec(times, times + deviceCount); - std::vector> mList; - std::vector> tList; - std::vector> vList; - mList.reserve(deviceCount); - tList.reserve(deviceCount); - vList.reserve(deviceCount); - for (int i = 0; i < deviceCount; i++) { - mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); - tList.push_back(toTypeVec(typesList[i], measurementCounts[i])); - vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i])); - } - session->cpp->insertAlignedRecords(devVec, timesVec, mList, tList, vList); - for (int i = 0; i < deviceCount; i++) { - freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]); - } - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); + const char* const* deviceIds, const int64_t* times, + const int* measurementCounts, + const char* const* const* measurementsList, + const TSDataType_C* const* typesList, + const void* const* const* valuesList) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto devVec = toStringVec(deviceIds, deviceCount); + std::vector timesVec(times, times + deviceCount); + std::vector> mList; + std::vector> tList; + std::vector> vList; + mList.reserve(deviceCount); + tList.reserve(deviceCount); + vList.reserve(deviceCount); + for (int i = 0; i < deviceCount; i++) { + mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); + tList.push_back(toTypeVec(typesList[i], measurementCounts[i])); + vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i])); + } + session->cpp->insertAlignedRecords(devVec, timesVec, mList, tList, vList); + for (int i = 0; i < deviceCount; i++) { + freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]); } + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ * Data Insertion — Batch, single device (typed values) * ============================================================ */ -TsStatus ts_session_insert_records_of_one_device(CSession* session, const char* deviceId, - int rowCount, const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const TSDataType_C* const* typesList, - const void* const* const* valuesList, - bool sorted) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - std::vector timesVec(times, times + rowCount); - std::vector> mList; - std::vector> tList; - std::vector> vList; - mList.reserve(rowCount); - tList.reserve(rowCount); - vList.reserve(rowCount); - for (int i = 0; i < rowCount; i++) { - mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); - tList.push_back(toTypeVec(typesList[i], measurementCounts[i])); - vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i])); - } - session->cpp->insertRecordsOfOneDevice(std::string(deviceId), timesVec, mList, tList, vList, sorted); - for (int i = 0; i < rowCount; i++) { - freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]); - } - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); +TsStatus ts_session_insert_records_of_one_device( + CSession* session, const char* deviceId, int rowCount, const int64_t* times, + const int* measurementCounts, const char* const* const* measurementsList, + const TSDataType_C* const* typesList, const void* const* const* valuesList, bool sorted) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + std::vector timesVec(times, times + rowCount); + std::vector> mList; + std::vector> tList; + std::vector> vList; + mList.reserve(rowCount); + tList.reserve(rowCount); + vList.reserve(rowCount); + for (int i = 0; i < rowCount; i++) { + mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); + tList.push_back(toTypeVec(typesList[i], measurementCounts[i])); + vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i])); + } + session->cpp->insertRecordsOfOneDevice(std::string(deviceId), timesVec, mList, tList, vList, + sorted); + for (int i = 0; i < rowCount; i++) { + freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]); } -} - -TsStatus ts_session_insert_aligned_records_of_one_device(CSession* session, const char* deviceId, - int rowCount, const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const TSDataType_C* const* typesList, - const void* const* const* valuesList, - bool sorted) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - std::vector timesVec(times, times + rowCount); - std::vector> mList; - std::vector> tList; - std::vector> vList; - mList.reserve(rowCount); - tList.reserve(rowCount); - vList.reserve(rowCount); - for (int i = 0; i < rowCount; i++) { - mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); - tList.push_back(toTypeVec(typesList[i], measurementCounts[i])); - vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i])); - } - session->cpp->insertAlignedRecordsOfOneDevice(std::string(deviceId), timesVec, mList, tList, vList, sorted); - for (int i = 0; i < rowCount; i++) { - freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]); - } - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_insert_aligned_records_of_one_device( + CSession* session, const char* deviceId, int rowCount, const int64_t* times, + const int* measurementCounts, const char* const* const* measurementsList, + const TSDataType_C* const* typesList, const void* const* const* valuesList, bool sorted) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + std::vector timesVec(times, times + rowCount); + std::vector> mList; + std::vector> tList; + std::vector> vList; + mList.reserve(rowCount); + tList.reserve(rowCount); + vList.reserve(rowCount); + for (int i = 0; i < rowCount; i++) { + mList.push_back(toStringVec(measurementsList[i], measurementCounts[i])); + tList.push_back(toTypeVec(typesList[i], measurementCounts[i])); + vList.push_back(toCharPtrVec(typesList[i], valuesList[i], measurementCounts[i])); + } + session->cpp->insertAlignedRecordsOfOneDevice(std::string(deviceId), timesVec, mList, tList, + vList, sorted); + for (int i = 0; i < rowCount; i++) { + freeCharPtrVec(vList[i], typesList[i], measurementCounts[i]); } + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ @@ -1000,61 +1025,66 @@ TsStatus ts_session_insert_aligned_records_of_one_device(CSession* session, cons * ============================================================ */ TsStatus ts_session_insert_tablet(CSession* session, CTablet* tablet, bool sorted) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!tablet) return setError(TS_ERR_NULL_PTR, "tablet is null"); - try { - session->cpp->insertTablet(tablet->cpp, sorted); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!tablet) + return setError(TS_ERR_NULL_PTR, "tablet is null"); + try { + session->cpp->insertTablet(tablet->cpp, sorted); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_session_insert_aligned_tablet(CSession* session, CTablet* tablet, bool sorted) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!tablet) return setError(TS_ERR_NULL_PTR, "tablet is null"); - try { - session->cpp->insertAlignedTablet(tablet->cpp, sorted); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_session_insert_tablets(CSession* session, int tabletCount, - const char* const* deviceIds, - CTablet** tablets, bool sorted) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - std::unordered_map tabletMap; - for (int i = 0; i < tabletCount; i++) { - tabletMap[std::string(deviceIds[i])] = &(tablets[i]->cpp); - } - session->cpp->insertTablets(tabletMap, sorted); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!tablet) + return setError(TS_ERR_NULL_PTR, "tablet is null"); + try { + session->cpp->insertAlignedTablet(tablet->cpp, sorted); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_insert_tablets(CSession* session, int tabletCount, const char* const* deviceIds, + CTablet** tablets, bool sorted) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + std::unordered_map tabletMap; + for (int i = 0; i < tabletCount; i++) { + tabletMap[std::string(deviceIds[i])] = &(tablets[i]->cpp); + } + session->cpp->insertTablets(tabletMap, sorted); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } TsStatus ts_session_insert_aligned_tablets(CSession* session, int tabletCount, - const char* const* deviceIds, - CTablet** tablets, bool sorted) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - std::unordered_map tabletMap; - for (int i = 0; i < tabletCount; i++) { - tabletMap[std::string(deviceIds[i])] = &(tablets[i]->cpp); - } - session->cpp->insertAlignedTablets(tabletMap, sorted); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + const char* const* deviceIds, CTablet** tablets, + bool sorted) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + std::unordered_map tabletMap; + for (int i = 0; i < tabletCount; i++) { + tabletMap[std::string(deviceIds[i])] = &(tablets[i]->cpp); + } + session->cpp->insertAlignedTablets(tabletMap, sorted); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ @@ -1062,134 +1092,142 @@ TsStatus ts_session_insert_aligned_tablets(CSession* session, int tabletCount, * ============================================================ */ TsStatus ts_table_session_insert(CTableSession* session, CTablet* tablet) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!tablet) return setError(TS_ERR_NULL_PTR, "tablet is null"); - try { - session->cpp->insert(tablet->cpp); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!tablet) + return setError(TS_ERR_NULL_PTR, "tablet is null"); + try { + session->cpp->insert(tablet->cpp); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ * Query — Tree Model * ============================================================ */ -TsStatus ts_session_execute_query(CSession* session, const char* sql, - CSessionDataSet** dataSet) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!dataSet) return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); - try { - auto ds = session->cpp->executeQueryStatement(std::string(sql)); - CSessionDataSet_ tmp{}; - tmp.cpp = std::move(ds); - auto* cds = new CSessionDataSet_(); - cds->cpp = std::move(tmp.cpp); - *dataSet = cds; - return TS_OK; - } catch (const std::exception& e) { - *dataSet = nullptr; - return handleException(e); - } +TsStatus ts_session_execute_query(CSession* session, const char* sql, CSessionDataSet** dataSet) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!dataSet) + return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); + try { + auto ds = session->cpp->executeQueryStatement(std::string(sql)); + CSessionDataSet_ tmp{}; + tmp.cpp = std::move(ds); + auto* cds = new CSessionDataSet_(); + cds->cpp = std::move(tmp.cpp); + *dataSet = cds; + return TS_OK; + } catch (const std::exception& e) { + *dataSet = nullptr; + return handleException(e); + } } TsStatus ts_session_execute_query_with_timeout(CSession* session, const char* sql, - int64_t timeoutInMs, - CSessionDataSet** dataSet) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!dataSet) return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); - try { - auto ds = session->cpp->executeQueryStatement(std::string(sql), timeoutInMs); - CSessionDataSet_ tmp{}; - tmp.cpp = std::move(ds); - auto* cds = new CSessionDataSet_(); - cds->cpp = std::move(tmp.cpp); - *dataSet = cds; - return TS_OK; - } catch (const std::exception& e) { - *dataSet = nullptr; - return handleException(e); - } + int64_t timeoutInMs, CSessionDataSet** dataSet) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!dataSet) + return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); + try { + auto ds = session->cpp->executeQueryStatement(std::string(sql), timeoutInMs); + CSessionDataSet_ tmp{}; + tmp.cpp = std::move(ds); + auto* cds = new CSessionDataSet_(); + cds->cpp = std::move(tmp.cpp); + *dataSet = cds; + return TS_OK; + } catch (const std::exception& e) { + *dataSet = nullptr; + return handleException(e); + } } TsStatus ts_session_execute_non_query(CSession* session, const char* sql) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->executeNonQueryStatement(std::string(sql)); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_session_execute_raw_data_query(CSession* session, - int pathCount, const char* const* paths, - int64_t startTime, int64_t endTime, - CSessionDataSet** dataSet) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!dataSet) return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); - try { - auto pathsVec = toStringVec(paths, pathCount); - auto ds = session->cpp->executeRawDataQuery(pathsVec, startTime, endTime); - CSessionDataSet_ tmp{}; - tmp.cpp = std::move(ds); - auto* cds = new CSessionDataSet_(); - cds->cpp = std::move(tmp.cpp); - *dataSet = cds; - return TS_OK; - } catch (const std::exception& e) { - *dataSet = nullptr; - return handleException(e); - } -} - -TsStatus ts_session_execute_last_data_query(CSession* session, - int pathCount, const char* const* paths, - CSessionDataSet** dataSet) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!dataSet) return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); - try { - auto pathsVec = toStringVec(paths, pathCount); - auto ds = session->cpp->executeLastDataQuery(pathsVec); - CSessionDataSet_ tmp{}; - tmp.cpp = std::move(ds); - auto* cds = new CSessionDataSet_(); - cds->cpp = std::move(tmp.cpp); - *dataSet = cds; - return TS_OK; - } catch (const std::exception& e) { - *dataSet = nullptr; - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->executeNonQueryStatement(std::string(sql)); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_execute_raw_data_query(CSession* session, int pathCount, + const char* const* paths, int64_t startTime, + int64_t endTime, CSessionDataSet** dataSet) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!dataSet) + return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); + try { + auto pathsVec = toStringVec(paths, pathCount); + auto ds = session->cpp->executeRawDataQuery(pathsVec, startTime, endTime); + CSessionDataSet_ tmp{}; + tmp.cpp = std::move(ds); + auto* cds = new CSessionDataSet_(); + cds->cpp = std::move(tmp.cpp); + *dataSet = cds; + return TS_OK; + } catch (const std::exception& e) { + *dataSet = nullptr; + return handleException(e); + } +} + +TsStatus ts_session_execute_last_data_query(CSession* session, int pathCount, + const char* const* paths, CSessionDataSet** dataSet) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!dataSet) + return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); + try { + auto pathsVec = toStringVec(paths, pathCount); + auto ds = session->cpp->executeLastDataQuery(pathsVec); + CSessionDataSet_ tmp{}; + tmp.cpp = std::move(ds); + auto* cds = new CSessionDataSet_(); + cds->cpp = std::move(tmp.cpp); + *dataSet = cds; + return TS_OK; + } catch (const std::exception& e) { + *dataSet = nullptr; + return handleException(e); + } } -TsStatus ts_session_execute_last_data_query_with_time(CSession* session, - int pathCount, const char* const* paths, - int64_t lastTime, - CSessionDataSet** dataSet) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!dataSet) return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); - try { - auto pathsVec = toStringVec(paths, pathCount); - auto ds = session->cpp->executeLastDataQuery(pathsVec, lastTime); - CSessionDataSet_ tmp{}; - tmp.cpp = std::move(ds); - auto* cds = new CSessionDataSet_(); - cds->cpp = std::move(tmp.cpp); - *dataSet = cds; - return TS_OK; - } catch (const std::exception& e) { - *dataSet = nullptr; - return handleException(e); - } +TsStatus ts_session_execute_last_data_query_with_time(CSession* session, int pathCount, + const char* const* paths, int64_t lastTime, + CSessionDataSet** dataSet) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!dataSet) + return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); + try { + auto pathsVec = toStringVec(paths, pathCount); + auto ds = session->cpp->executeLastDataQuery(pathsVec, lastTime); + CSessionDataSet_ tmp{}; + tmp.cpp = std::move(ds); + auto* cds = new CSessionDataSet_(); + cds->cpp = std::move(tmp.cpp); + *dataSet = cds; + return TS_OK; + } catch (const std::exception& e) { + *dataSet = nullptr; + return handleException(e); + } } /* ============================================================ @@ -1197,53 +1235,58 @@ TsStatus ts_session_execute_last_data_query_with_time(CSession* session, * ============================================================ */ TsStatus ts_table_session_execute_query(CTableSession* session, const char* sql, - CSessionDataSet** dataSet) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!dataSet) return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); - try { - auto ds = session->cpp->executeQueryStatement(std::string(sql)); - CSessionDataSet_ tmp{}; - tmp.cpp = std::move(ds); - auto* cds = new CSessionDataSet_(); - cds->cpp = std::move(tmp.cpp); - *dataSet = cds; - return TS_OK; - } catch (const std::exception& e) { - *dataSet = nullptr; - return handleException(e); - } + CSessionDataSet** dataSet) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!dataSet) + return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); + try { + auto ds = session->cpp->executeQueryStatement(std::string(sql)); + CSessionDataSet_ tmp{}; + tmp.cpp = std::move(ds); + auto* cds = new CSessionDataSet_(); + cds->cpp = std::move(tmp.cpp); + *dataSet = cds; + return TS_OK; + } catch (const std::exception& e) { + *dataSet = nullptr; + return handleException(e); + } } TsStatus ts_table_session_execute_query_with_timeout(CTableSession* session, const char* sql, - int64_t timeoutInMs, - CSessionDataSet** dataSet) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - if (!dataSet) return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); - try { - auto ds = session->cpp->executeQueryStatement(std::string(sql), timeoutInMs); - CSessionDataSet_ tmp{}; - tmp.cpp = std::move(ds); - auto* cds = new CSessionDataSet_(); - cds->cpp = std::move(tmp.cpp); - *dataSet = cds; - return TS_OK; - } catch (const std::exception& e) { - *dataSet = nullptr; - return handleException(e); - } + int64_t timeoutInMs, + CSessionDataSet** dataSet) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + if (!dataSet) + return setError(TS_ERR_INVALID_PARAM, "dataSet pointer is null"); + try { + auto ds = session->cpp->executeQueryStatement(std::string(sql), timeoutInMs); + CSessionDataSet_ tmp{}; + tmp.cpp = std::move(ds); + auto* cds = new CSessionDataSet_(); + cds->cpp = std::move(tmp.cpp); + *dataSet = cds; + return TS_OK; + } catch (const std::exception& e) { + *dataSet = nullptr; + return handleException(e); + } } TsStatus ts_table_session_execute_non_query(CTableSession* session, const char* sql) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->executeNonQueryStatement(std::string(sql)); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->executeNonQueryStatement(std::string(sql)); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } /* ============================================================ @@ -1251,165 +1294,189 @@ TsStatus ts_table_session_execute_non_query(CTableSession* session, const char* * ============================================================ */ void ts_dataset_destroy(CSessionDataSet* dataSet) { - if (dataSet) { - if (dataSet->cpp) { - dataSet->cpp->closeOperationHandle(); - } - delete dataSet; + if (dataSet) { + if (dataSet->cpp) { + dataSet->cpp->closeOperationHandle(); } + delete dataSet; + } } bool ts_dataset_has_next(CSessionDataSet* dataSet) { - clearError(); - if (!dataSet) { - (void)setError(TS_ERR_NULL_PTR, "dataSet is null"); - return false; - } - if (!dataSet->cpp) { - (void)setError(TS_ERR_NULL_PTR, "dataSet is not initialized"); - return false; - } - try { - return dataSet->cpp->hasNext(); - } catch (const std::exception& e) { - (void)handleException(e); - return false; - } catch (...) { - (void)setError(TS_ERR_UNKNOWN, "non-standard exception"); - return false; - } + clearError(); + if (!dataSet) { + (void)setError(TS_ERR_NULL_PTR, "dataSet is null"); + return false; + } + if (!dataSet->cpp) { + (void)setError(TS_ERR_NULL_PTR, "dataSet is not initialized"); + return false; + } + try { + return dataSet->cpp->hasNext(); + } catch (const std::exception& e) { + (void)handleException(e); + return false; + } catch (...) { + (void)setError(TS_ERR_UNKNOWN, "non-standard exception"); + return false; + } } CRowRecord* ts_dataset_next(CSessionDataSet* dataSet) { - clearError(); - if (!dataSet) { - (void)setError(TS_ERR_NULL_PTR, "dataSet is null"); - return nullptr; - } - if (!dataSet->cpp) { - (void)setError(TS_ERR_NULL_PTR, "dataSet is not initialized"); - return nullptr; - } - try { - auto row = dataSet->cpp->next(); - if (!row) return nullptr; - CRowRecord_ tmp{}; - tmp.cpp = std::move(row); - auto* crr = new CRowRecord_(); - crr->cpp = std::move(tmp.cpp); - return crr; - } catch (const std::exception& e) { - (void)handleException(e); - return nullptr; - } catch (...) { - (void)setError(TS_ERR_UNKNOWN, "non-standard exception"); - return nullptr; - } + clearError(); + if (!dataSet) { + (void)setError(TS_ERR_NULL_PTR, "dataSet is null"); + return nullptr; + } + if (!dataSet->cpp) { + (void)setError(TS_ERR_NULL_PTR, "dataSet is not initialized"); + return nullptr; + } + try { + auto row = dataSet->cpp->next(); + if (!row) + return nullptr; + CRowRecord_ tmp{}; + tmp.cpp = std::move(row); + auto* crr = new CRowRecord_(); + crr->cpp = std::move(tmp.cpp); + return crr; + } catch (const std::exception& e) { + (void)handleException(e); + return nullptr; + } catch (...) { + (void)setError(TS_ERR_UNKNOWN, "non-standard exception"); + return nullptr; + } } int ts_dataset_get_column_count(CSessionDataSet* dataSet) { - if (!dataSet || !dataSet->cpp) return 0; - return static_cast(dataSet->cpp->getColumnNames().size()); + if (!dataSet || !dataSet->cpp) + return 0; + return static_cast(dataSet->cpp->getColumnNames().size()); } static thread_local std::string g_colNameBuf; const char* ts_dataset_get_column_name(CSessionDataSet* dataSet, int index) { - if (!dataSet || !dataSet->cpp) return ""; - const auto& names = dataSet->cpp->getColumnNames(); - if (index < 0 || index >= (int)names.size()) return ""; - g_colNameBuf = names[index]; - return g_colNameBuf.c_str(); + if (!dataSet || !dataSet->cpp) + return ""; + const auto& names = dataSet->cpp->getColumnNames(); + if (index < 0 || index >= (int)names.size()) + return ""; + g_colNameBuf = names[index]; + return g_colNameBuf.c_str(); } static thread_local std::string g_colTypeBuf; const char* ts_dataset_get_column_type(CSessionDataSet* dataSet, int index) { - if (!dataSet || !dataSet->cpp) return ""; - const auto& types = dataSet->cpp->getColumnTypeList(); - if (index < 0 || index >= (int)types.size()) return ""; - g_colTypeBuf = types[index]; - return g_colTypeBuf.c_str(); + if (!dataSet || !dataSet->cpp) + return ""; + const auto& types = dataSet->cpp->getColumnTypeList(); + if (index < 0 || index >= (int)types.size()) + return ""; + g_colTypeBuf = types[index]; + return g_colTypeBuf.c_str(); } void ts_dataset_set_fetch_size(CSessionDataSet* dataSet, int fetchSize) { - if (dataSet && dataSet->cpp) { - dataSet->cpp->setFetchSize(fetchSize); - } + if (dataSet && dataSet->cpp) { + dataSet->cpp->setFetchSize(fetchSize); + } } void ts_row_record_destroy(CRowRecord* record) { - delete record; + delete record; } int64_t ts_row_record_get_timestamp(CRowRecord* record) { - if (!record || !record->cpp) return -1; - return record->cpp->timestamp; + if (!record || !record->cpp) + return -1; + return record->cpp->timestamp; } int ts_row_record_get_field_count(CRowRecord* record) { - if (!record || !record->cpp) return 0; - return static_cast(record->cpp->fields.size()); + if (!record || !record->cpp) + return 0; + return static_cast(record->cpp->fields.size()); } bool ts_row_record_is_null(CRowRecord* record, int index) { - if (!record || !record->cpp) return true; - if (index < 0 || index >= (int)record->cpp->fields.size()) return true; - return record->cpp->fields[index].isNull(); + if (!record || !record->cpp) + return true; + if (index < 0 || index >= (int)record->cpp->fields.size()) + return true; + return record->cpp->fields[index].isNull(); } bool ts_row_record_get_bool(CRowRecord* record, int index) { - if (!record || !record->cpp) return false; - if (index < 0 || index >= (int)record->cpp->fields.size()) return false; - const Field& f = record->cpp->fields[index]; - return f.boolV.is_initialized() ? f.boolV.value() : false; + if (!record || !record->cpp) + return false; + if (index < 0 || index >= (int)record->cpp->fields.size()) + return false; + const Field& f = record->cpp->fields[index]; + return f.boolV.is_initialized() ? f.boolV.value() : false; } int32_t ts_row_record_get_int32(CRowRecord* record, int index) { - if (!record || !record->cpp) return 0; - if (index < 0 || index >= (int)record->cpp->fields.size()) return 0; - const Field& f = record->cpp->fields[index]; - return f.intV.is_initialized() ? f.intV.value() : 0; + if (!record || !record->cpp) + return 0; + if (index < 0 || index >= (int)record->cpp->fields.size()) + return 0; + const Field& f = record->cpp->fields[index]; + return f.intV.is_initialized() ? f.intV.value() : 0; } int64_t ts_row_record_get_int64(CRowRecord* record, int index) { - if (!record || !record->cpp) return 0; - if (index < 0 || index >= (int)record->cpp->fields.size()) return 0; - const Field& f = record->cpp->fields[index]; - return f.longV.is_initialized() ? f.longV.value() : 0; + if (!record || !record->cpp) + return 0; + if (index < 0 || index >= (int)record->cpp->fields.size()) + return 0; + const Field& f = record->cpp->fields[index]; + return f.longV.is_initialized() ? f.longV.value() : 0; } float ts_row_record_get_float(CRowRecord* record, int index) { - if (!record || !record->cpp) return 0.0f; - if (index < 0 || index >= (int)record->cpp->fields.size()) return 0.0f; - const Field& f = record->cpp->fields[index]; - return f.floatV.is_initialized() ? f.floatV.value() : 0.0f; + if (!record || !record->cpp) + return 0.0f; + if (index < 0 || index >= (int)record->cpp->fields.size()) + return 0.0f; + const Field& f = record->cpp->fields[index]; + return f.floatV.is_initialized() ? f.floatV.value() : 0.0f; } double ts_row_record_get_double(CRowRecord* record, int index) { - if (!record || !record->cpp) return 0.0; - if (index < 0 || index >= (int)record->cpp->fields.size()) return 0.0; - const Field& f = record->cpp->fields[index]; - return f.doubleV.is_initialized() ? f.doubleV.value() : 0.0; + if (!record || !record->cpp) + return 0.0; + if (index < 0 || index >= (int)record->cpp->fields.size()) + return 0.0; + const Field& f = record->cpp->fields[index]; + return f.doubleV.is_initialized() ? f.doubleV.value() : 0.0; } static thread_local std::string g_stringBuf; const char* ts_row_record_get_string(CRowRecord* record, int index) { - if (!record || !record->cpp) return ""; - if (index < 0 || index >= (int)record->cpp->fields.size()) return ""; - const Field& f = record->cpp->fields[index]; - if (f.stringV.is_initialized()) { - g_stringBuf = f.stringV.value(); - return g_stringBuf.c_str(); - } + if (!record || !record->cpp) + return ""; + if (index < 0 || index >= (int)record->cpp->fields.size()) return ""; + const Field& f = record->cpp->fields[index]; + if (f.stringV.is_initialized()) { + g_stringBuf = f.stringV.value(); + return g_stringBuf.c_str(); + } + return ""; } TSDataType_C ts_row_record_get_data_type(CRowRecord* record, int index) { - if (!record || !record->cpp) return TS_TYPE_INVALID; - if (index < 0 || index >= (int)record->cpp->fields.size()) return TS_TYPE_INVALID; - return static_cast(record->cpp->fields[index].dataType); + if (!record || !record->cpp) + return TS_TYPE_INVALID; + if (index < 0 || index >= (int)record->cpp->fields.size()) + return TS_TYPE_INVALID; + return static_cast(record->cpp->fields[index].dataType); } /* ============================================================ @@ -1417,41 +1484,43 @@ TSDataType_C ts_row_record_get_data_type(CRowRecord* record, int index) { * ============================================================ */ TsStatus ts_session_delete_data(CSession* session, const char* path, int64_t endTime) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - session->cpp->deleteData(std::string(path), endTime); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_session_delete_data_batch(CSession* session, int pathCount, - const char* const* paths, int64_t endTime) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto pathsVec = toStringVec(paths, pathCount); - session->cpp->deleteData(pathsVec, endTime); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } -} - -TsStatus ts_session_delete_data_range(CSession* session, int pathCount, - const char* const* paths, - int64_t startTime, int64_t endTime) { - clearError(); - if (!session) return setError(TS_ERR_NULL_PTR, "session is null"); - try { - auto pathsVec = toStringVec(paths, pathCount); - session->cpp->deleteData(pathsVec, startTime, endTime); - return TS_OK; - } catch (const std::exception& e) { - return handleException(e); - } + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + session->cpp->deleteData(std::string(path), endTime); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_delete_data_batch(CSession* session, int pathCount, const char* const* paths, + int64_t endTime) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto pathsVec = toStringVec(paths, pathCount); + session->cpp->deleteData(pathsVec, endTime); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } +} + +TsStatus ts_session_delete_data_range(CSession* session, int pathCount, const char* const* paths, + int64_t startTime, int64_t endTime) { + clearError(); + if (!session) + return setError(TS_ERR_NULL_PTR, "session is null"); + try { + auto pathsVec = toStringVec(paths, pathCount); + session->cpp->deleteData(pathsVec, startTime, endTime); + return TS_OK; + } catch (const std::exception& e) { + return handleException(e); + } } -} /* extern "C" */ +} /* extern "C" */ diff --git a/iotdb-client/client-cpp/src/main/SessionC.h b/iotdb-client/client-cpp/src/main/SessionC.h index 77fbdbd51fc83..5c850c09c123b 100644 --- a/iotdb-client/client-cpp/src/main/SessionC.h +++ b/iotdb-client/client-cpp/src/main/SessionC.h @@ -34,12 +34,12 @@ extern "C" { typedef int64_t TsStatus; -#define TS_OK 0 -#define TS_ERR_CONNECTION -1 -#define TS_ERR_EXECUTION -2 -#define TS_ERR_INVALID_PARAM -3 -#define TS_ERR_NULL_PTR -4 -#define TS_ERR_UNKNOWN -99 +#define TS_OK 0 +#define TS_ERR_CONNECTION -1 +#define TS_ERR_EXECUTION -2 +#define TS_ERR_INVALID_PARAM -3 +#define TS_ERR_NULL_PTR -4 +#define TS_ERR_UNKNOWN -99 /** * Returns the error message from the last failed C API call on the current thread. @@ -51,77 +51,71 @@ const char* ts_get_last_error(void); * Opaque Handle Types * ============================================================ */ -typedef struct CSession_ CSession; -typedef struct CTableSession_ CTableSession; -typedef struct CTablet_ CTablet; +typedef struct CSession_ CSession; +typedef struct CTableSession_ CTableSession; +typedef struct CTablet_ CTablet; typedef struct CSessionDataSet_ CSessionDataSet; -typedef struct CRowRecord_ CRowRecord; +typedef struct CRowRecord_ CRowRecord; /* ============================================================ * Enums (values match C++ TSDataType / TSEncoding / CompressionType) * ============================================================ */ typedef enum { - TS_TYPE_BOOLEAN = 0, - TS_TYPE_INT32 = 1, - TS_TYPE_INT64 = 2, - TS_TYPE_FLOAT = 3, - TS_TYPE_DOUBLE = 4, - TS_TYPE_TEXT = 5, - TS_TYPE_TIMESTAMP = 8, - TS_TYPE_DATE = 9, - TS_TYPE_BLOB = 10, - TS_TYPE_STRING = 11, - /** Not a server type; used for invalid arguments / error paths in the C API. */ - TS_TYPE_INVALID = 255 + TS_TYPE_BOOLEAN = 0, + TS_TYPE_INT32 = 1, + TS_TYPE_INT64 = 2, + TS_TYPE_FLOAT = 3, + TS_TYPE_DOUBLE = 4, + TS_TYPE_TEXT = 5, + TS_TYPE_TIMESTAMP = 8, + TS_TYPE_DATE = 9, + TS_TYPE_BLOB = 10, + TS_TYPE_STRING = 11, + /** Not a server type; used for invalid arguments / error paths in the C API. */ + TS_TYPE_INVALID = 255 } TSDataType_C; typedef enum { - TS_ENCODING_PLAIN = 0, - TS_ENCODING_DICTIONARY = 1, - TS_ENCODING_RLE = 2, - TS_ENCODING_DIFF = 3, - TS_ENCODING_TS_2DIFF = 4, - TS_ENCODING_BITMAP = 5, - TS_ENCODING_GORILLA_V1 = 6, - TS_ENCODING_REGULAR = 7, - TS_ENCODING_GORILLA = 8, - TS_ENCODING_ZIGZAG = 9, - TS_ENCODING_FREQ = 10 + TS_ENCODING_PLAIN = 0, + TS_ENCODING_DICTIONARY = 1, + TS_ENCODING_RLE = 2, + TS_ENCODING_DIFF = 3, + TS_ENCODING_TS_2DIFF = 4, + TS_ENCODING_BITMAP = 5, + TS_ENCODING_GORILLA_V1 = 6, + TS_ENCODING_REGULAR = 7, + TS_ENCODING_GORILLA = 8, + TS_ENCODING_ZIGZAG = 9, + TS_ENCODING_FREQ = 10 } TSEncoding_C; typedef enum { - TS_COMPRESSION_UNCOMPRESSED = 0, - TS_COMPRESSION_SNAPPY = 1, - TS_COMPRESSION_GZIP = 2, - TS_COMPRESSION_LZO = 3, - TS_COMPRESSION_SDT = 4, - TS_COMPRESSION_PAA = 5, - TS_COMPRESSION_PLA = 6, - TS_COMPRESSION_LZ4 = 7, - TS_COMPRESSION_ZSTD = 8, - TS_COMPRESSION_LZMA2 = 9 + TS_COMPRESSION_UNCOMPRESSED = 0, + TS_COMPRESSION_SNAPPY = 1, + TS_COMPRESSION_GZIP = 2, + TS_COMPRESSION_LZO = 3, + TS_COMPRESSION_SDT = 4, + TS_COMPRESSION_PAA = 5, + TS_COMPRESSION_PLA = 6, + TS_COMPRESSION_LZ4 = 7, + TS_COMPRESSION_ZSTD = 8, + TS_COMPRESSION_LZMA2 = 9 } TSCompressionType_C; -typedef enum { - TS_COL_TAG = 0, - TS_COL_FIELD = 1, - TS_COL_ATTRIBUTE = 2 -} TSColumnCategory_C; +typedef enum { TS_COL_TAG = 0, TS_COL_FIELD = 1, TS_COL_ATTRIBUTE = 2 } TSColumnCategory_C; /* ============================================================ * Session Lifecycle — Tree Model * ============================================================ */ -CSession* ts_session_new(const char* host, int rpcPort, - const char* username, const char* password); +CSession* ts_session_new(const char* host, int rpcPort, const char* username, const char* password); -CSession* ts_session_new_with_zone(const char* host, int rpcPort, - const char* username, const char* password, - const char* zoneId, int fetchSize); +CSession* ts_session_new_with_zone(const char* host, int rpcPort, const char* username, + const char* password, const char* zoneId, int fetchSize); -CSession* ts_session_new_multi_node(const char* const* nodeUrls, int urlCount, - const char* username, const char* password); +CSession* ts_session_new_multi_node(const char* const* nodeUrls, int urlCount, const char* username, + const char* password); void ts_session_destroy(CSession* session); @@ -135,13 +129,12 @@ TsStatus ts_session_close(CSession* session); * Session Lifecycle — Table Model * ============================================================ */ -CTableSession* ts_table_session_new(const char* host, int rpcPort, - const char* username, const char* password, - const char* database); +CTableSession* ts_table_session_new(const char* host, int rpcPort, const char* username, + const char* password, const char* database); CTableSession* ts_table_session_new_multi_node(const char* const* nodeUrls, int urlCount, - const char* username, const char* password, - const char* database); + const char* username, const char* password, + const char* database); void ts_table_session_destroy(CTableSession* session); @@ -171,36 +164,28 @@ TsStatus ts_session_delete_databases(CSession* session, const char* const* datab * Timeseries Management (Tree Model) * ============================================================ */ -TsStatus ts_session_create_timeseries(CSession* session, const char* path, - TSDataType_C dataType, TSEncoding_C encoding, - TSCompressionType_C compressor); - -TsStatus ts_session_create_timeseries_ex(CSession* session, const char* path, - TSDataType_C dataType, TSEncoding_C encoding, - TSCompressionType_C compressor, - int propsCount, - const char* const* propKeys, - const char* const* propValues, - int tagsCount, - const char* const* tagKeys, - const char* const* tagValues, - int attrsCount, - const char* const* attrKeys, - const char* const* attrValues, - const char* measurementAlias); - -TsStatus ts_session_create_multi_timeseries(CSession* session, int count, - const char* const* paths, - const TSDataType_C* dataTypes, - const TSEncoding_C* encodings, - const TSCompressionType_C* compressors); - -TsStatus ts_session_create_aligned_timeseries(CSession* session, const char* deviceId, - int count, - const char* const* measurements, - const TSDataType_C* dataTypes, - const TSEncoding_C* encodings, - const TSCompressionType_C* compressors); +TsStatus ts_session_create_timeseries(CSession* session, const char* path, TSDataType_C dataType, + TSEncoding_C encoding, TSCompressionType_C compressor); + +TsStatus ts_session_create_timeseries_ex(CSession* session, const char* path, TSDataType_C dataType, + TSEncoding_C encoding, TSCompressionType_C compressor, + int propsCount, const char* const* propKeys, + const char* const* propValues, int tagsCount, + const char* const* tagKeys, const char* const* tagValues, + int attrsCount, const char* const* attrKeys, + const char* const* attrValues, + const char* measurementAlias); + +TsStatus ts_session_create_multi_timeseries(CSession* session, int count, const char* const* paths, + const TSDataType_C* dataTypes, + const TSEncoding_C* encodings, + const TSCompressionType_C* compressors); + +TsStatus ts_session_create_aligned_timeseries(CSession* session, const char* deviceId, int count, + const char* const* measurements, + const TSDataType_C* dataTypes, + const TSEncoding_C* encodings, + const TSCompressionType_C* compressors); TsStatus ts_session_check_timeseries_exists(CSession* session, const char* path, bool* exists); @@ -212,16 +197,12 @@ TsStatus ts_session_delete_timeseries_batch(CSession* session, const char* const * Tablet Operations * ============================================================ */ -CTablet* ts_tablet_new(const char* deviceId, int columnCount, - const char* const* columnNames, - const TSDataType_C* dataTypes, - int maxRowNumber); +CTablet* ts_tablet_new(const char* deviceId, int columnCount, const char* const* columnNames, + const TSDataType_C* dataTypes, int maxRowNumber); CTablet* ts_tablet_new_with_category(const char* deviceId, int columnCount, - const char* const* columnNames, - const TSDataType_C* dataTypes, - const TSColumnCategory_C* columnCategories, - int maxRowNumber); + const char* const* columnNames, const TSDataType_C* dataTypes, + const TSColumnCategory_C* columnCategories, int maxRowNumber); void ts_tablet_destroy(CTablet* tablet); @@ -249,76 +230,61 @@ TsStatus ts_tablet_add_value_string(CTablet* tablet, int colIndex, int rowIndex, * Data Insertion — Tree Model (Record) * ============================================================ */ -TsStatus ts_session_insert_record_str(CSession* session, const char* deviceId, - int64_t time, int count, - const char* const* measurements, - const char* const* values); +TsStatus ts_session_insert_record_str(CSession* session, const char* deviceId, int64_t time, + int count, const char* const* measurements, + const char* const* values); -TsStatus ts_session_insert_record(CSession* session, const char* deviceId, - int64_t time, int count, - const char* const* measurements, - const TSDataType_C* types, - const void* const* values); +TsStatus ts_session_insert_record(CSession* session, const char* deviceId, int64_t time, int count, + const char* const* measurements, const TSDataType_C* types, + const void* const* values); -TsStatus ts_session_insert_aligned_record_str(CSession* session, const char* deviceId, - int64_t time, int count, - const char* const* measurements, - const char* const* values); +TsStatus ts_session_insert_aligned_record_str(CSession* session, const char* deviceId, int64_t time, + int count, const char* const* measurements, + const char* const* values); -TsStatus ts_session_insert_aligned_record(CSession* session, const char* deviceId, - int64_t time, int count, - const char* const* measurements, - const TSDataType_C* types, - const void* const* values); +TsStatus ts_session_insert_aligned_record(CSession* session, const char* deviceId, int64_t time, + int count, const char* const* measurements, + const TSDataType_C* types, const void* const* values); /* Batch insert — multiple devices (string values) */ TsStatus ts_session_insert_records_str(CSession* session, int deviceCount, - const char* const* deviceIds, - const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const char* const* const* valuesList); + const char* const* deviceIds, const int64_t* times, + const int* measurementCounts, + const char* const* const* measurementsList, + const char* const* const* valuesList); TsStatus ts_session_insert_aligned_records_str(CSession* session, int deviceCount, - const char* const* deviceIds, - const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const char* const* const* valuesList); + const char* const* deviceIds, const int64_t* times, + const int* measurementCounts, + const char* const* const* measurementsList, + const char* const* const* valuesList); /* Batch insert — multiple devices (typed values) */ -TsStatus ts_session_insert_records(CSession* session, int deviceCount, - const char* const* deviceIds, - const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const TSDataType_C* const* typesList, - const void* const* const* valuesList); +TsStatus ts_session_insert_records(CSession* session, int deviceCount, const char* const* deviceIds, + const int64_t* times, const int* measurementCounts, + const char* const* const* measurementsList, + const TSDataType_C* const* typesList, + const void* const* const* valuesList); TsStatus ts_session_insert_aligned_records(CSession* session, int deviceCount, - const char* const* deviceIds, - const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const TSDataType_C* const* typesList, - const void* const* const* valuesList); + const char* const* deviceIds, const int64_t* times, + const int* measurementCounts, + const char* const* const* measurementsList, + const TSDataType_C* const* typesList, + const void* const* const* valuesList); /* Batch insert — single device (typed values) */ TsStatus ts_session_insert_records_of_one_device(CSession* session, const char* deviceId, - int rowCount, const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const TSDataType_C* const* typesList, - const void* const* const* valuesList, - bool sorted); - -TsStatus ts_session_insert_aligned_records_of_one_device(CSession* session, const char* deviceId, - int rowCount, const int64_t* times, - const int* measurementCounts, - const char* const* const* measurementsList, - const TSDataType_C* const* typesList, - const void* const* const* valuesList, - bool sorted); + int rowCount, const int64_t* times, + const int* measurementCounts, + const char* const* const* measurementsList, + const TSDataType_C* const* typesList, + const void* const* const* valuesList, bool sorted); + +TsStatus ts_session_insert_aligned_records_of_one_device( + CSession* session, const char* deviceId, int rowCount, const int64_t* times, + const int* measurementCounts, const char* const* const* measurementsList, + const TSDataType_C* const* typesList, const void* const* const* valuesList, bool sorted); /* ============================================================ * Data Insertion — Tree Model (Tablet) @@ -328,13 +294,12 @@ TsStatus ts_session_insert_tablet(CSession* session, CTablet* tablet, bool sorte TsStatus ts_session_insert_aligned_tablet(CSession* session, CTablet* tablet, bool sorted); -TsStatus ts_session_insert_tablets(CSession* session, int tabletCount, - const char* const* deviceIds, - CTablet** tablets, bool sorted); +TsStatus ts_session_insert_tablets(CSession* session, int tabletCount, const char* const* deviceIds, + CTablet** tablets, bool sorted); TsStatus ts_session_insert_aligned_tablets(CSession* session, int tabletCount, - const char* const* deviceIds, - CTablet** tablets, bool sorted); + const char* const* deviceIds, CTablet** tablets, + bool sorted); /* ============================================================ * Data Insertion — Table Model (Tablet) @@ -346,39 +311,34 @@ TsStatus ts_table_session_insert(CTableSession* session, CTablet* tablet); * Query — Tree Model * ============================================================ */ -TsStatus ts_session_execute_query(CSession* session, const char* sql, - CSessionDataSet** dataSet); +TsStatus ts_session_execute_query(CSession* session, const char* sql, CSessionDataSet** dataSet); TsStatus ts_session_execute_query_with_timeout(CSession* session, const char* sql, - int64_t timeoutInMs, - CSessionDataSet** dataSet); + int64_t timeoutInMs, CSessionDataSet** dataSet); TsStatus ts_session_execute_non_query(CSession* session, const char* sql); -TsStatus ts_session_execute_raw_data_query(CSession* session, - int pathCount, const char* const* paths, - int64_t startTime, int64_t endTime, - CSessionDataSet** dataSet); +TsStatus ts_session_execute_raw_data_query(CSession* session, int pathCount, + const char* const* paths, int64_t startTime, + int64_t endTime, CSessionDataSet** dataSet); -TsStatus ts_session_execute_last_data_query(CSession* session, - int pathCount, const char* const* paths, - CSessionDataSet** dataSet); +TsStatus ts_session_execute_last_data_query(CSession* session, int pathCount, + const char* const* paths, CSessionDataSet** dataSet); -TsStatus ts_session_execute_last_data_query_with_time(CSession* session, - int pathCount, const char* const* paths, - int64_t lastTime, - CSessionDataSet** dataSet); +TsStatus ts_session_execute_last_data_query_with_time(CSession* session, int pathCount, + const char* const* paths, int64_t lastTime, + CSessionDataSet** dataSet); /* ============================================================ * Query — Table Model * ============================================================ */ TsStatus ts_table_session_execute_query(CTableSession* session, const char* sql, - CSessionDataSet** dataSet); + CSessionDataSet** dataSet); TsStatus ts_table_session_execute_query_with_timeout(CTableSession* session, const char* sql, - int64_t timeoutInMs, - CSessionDataSet** dataSet); + int64_t timeoutInMs, + CSessionDataSet** dataSet); TsStatus ts_table_session_execute_non_query(CTableSession* session, const char* sql); @@ -431,15 +391,14 @@ TSDataType_C ts_row_record_get_data_type(CRowRecord* record, int index); TsStatus ts_session_delete_data(CSession* session, const char* path, int64_t endTime); -TsStatus ts_session_delete_data_batch(CSession* session, int pathCount, - const char* const* paths, int64_t endTime); +TsStatus ts_session_delete_data_batch(CSession* session, int pathCount, const char* const* paths, + int64_t endTime); -TsStatus ts_session_delete_data_range(CSession* session, int pathCount, - const char* const* paths, - int64_t startTime, int64_t endTime); +TsStatus ts_session_delete_data_range(CSession* session, int pathCount, const char* const* paths, + int64_t startTime, int64_t endTime); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif #endif /* IOTDB_SESSION_C_H */ diff --git a/iotdb-client/client-cpp/src/main/SessionConnection.cpp b/iotdb-client/client-cpp/src/main/SessionConnection.cpp index e4d369374c84e..a7fa3beb6ffc4 100644 --- a/iotdb-client/client-cpp/src/main/SessionConnection.cpp +++ b/iotdb-client/client-cpp/src/main/SessionConnection.cpp @@ -31,666 +31,617 @@ using namespace apache::thrift::transport; SessionConnection::SessionConnection(Session* session_ptr, const TEndPoint& endpoint, const std::string& zoneId, - std::shared_ptr nodeSupplier, - int fetchSize, - int maxRetries, - int64_t retryInterval, - int64_t connectionTimeout, - std::string dialect, - std::string db) - : session(session_ptr), - zoneId(zoneId), - endPoint(endpoint), - availableNodes(std::move(nodeSupplier)), - fetchSize(fetchSize), - maxRetryCount(maxRetries), - retryIntervalMs(retryInterval), - connectionTimeoutInMs(connectionTimeout), - sqlDialect(std::move(dialect)), - database(std::move(db)) { - this->zoneId = zoneId.empty() ? getSystemDefaultZoneId() : zoneId; - endPointList.push_back(endpoint); - init(endPoint, session->useSSL_, session->trustCertFilePath_); + std::shared_ptr nodeSupplier, int fetchSize, + int maxRetries, int64_t retryInterval, + int64_t connectionTimeout, std::string dialect, std::string db) + : session(session_ptr), zoneId(zoneId), endPoint(endpoint), + availableNodes(std::move(nodeSupplier)), fetchSize(fetchSize), maxRetryCount(maxRetries), + retryIntervalMs(retryInterval), connectionTimeoutInMs(connectionTimeout), + sqlDialect(std::move(dialect)), database(std::move(db)) { + this->zoneId = zoneId.empty() ? getSystemDefaultZoneId() : zoneId; + endPointList.push_back(endpoint); + init(endPoint, session->useSSL_, session->trustCertFilePath_); } void SessionConnection::close() { - bool needThrowException = false; - string errMsg; - session = nullptr; - try { - TSCloseSessionReq req; - req.__set_sessionId(sessionId); - TSStatus tsStatus; - client->closeSession(tsStatus, req); - } - catch (const TTransportException& e) { - log_debug(e.what()); - throw IoTDBConnectionException(e.what()); - } catch (const exception& e) { - log_debug(e.what()); - errMsg = errMsg + "Session::close() client->closeSession() error, maybe remote server is down. " + e.what() + - "\n"; - needThrowException = true; - } - - try { - if (transport->isOpen()) { - transport->close(); - } - } - catch (const exception& e) { - log_debug(e.what()); - errMsg = errMsg + "Session::close() transport->close() error. " + e.what() + "\n"; - needThrowException = true; + bool needThrowException = false; + string errMsg; + session = nullptr; + try { + TSCloseSessionReq req; + req.__set_sessionId(sessionId); + TSStatus tsStatus; + client->closeSession(tsStatus, req); + } catch (const TTransportException& e) { + log_debug(e.what()); + throw IoTDBConnectionException(e.what()); + } catch (const exception& e) { + log_debug(e.what()); + errMsg = errMsg + + "Session::close() client->closeSession() error, maybe remote server is down. " + + e.what() + "\n"; + needThrowException = true; + } + + try { + if (transport->isOpen()) { + transport->close(); } + } catch (const exception& e) { + log_debug(e.what()); + errMsg = errMsg + "Session::close() transport->close() error. " + e.what() + "\n"; + needThrowException = true; + } - if (needThrowException) { - throw IoTDBException(errMsg); - } + if (needThrowException) { + throw IoTDBException(errMsg); + } } SessionConnection::~SessionConnection() { - try { - close(); - } - catch (const exception& e) { - log_debug(e.what()); - } + try { + close(); + } catch (const exception& e) { + log_debug(e.what()); + } } -void SessionConnection::init(const TEndPoint& endpoint, bool useSSL, const std::string& trustCertFilePath) { - if (useSSL) { +void SessionConnection::init(const TEndPoint& endpoint, bool useSSL, + const std::string& trustCertFilePath) { + if (useSSL) { #if WITH_SSL - socketFactory_->loadTrustedCertificates(trustCertFilePath.c_str()); - socketFactory_->authenticate(false); - auto sslSocket = socketFactory_->createSocket(endPoint.ip, endPoint.port); - sslSocket->setConnTimeout(connectionTimeoutInMs); - transport = std::make_shared(sslSocket); + socketFactory_->loadTrustedCertificates(trustCertFilePath.c_str()); + socketFactory_->authenticate(false); + auto sslSocket = socketFactory_->createSocket(endPoint.ip, endPoint.port); + sslSocket->setConnTimeout(connectionTimeoutInMs); + transport = std::make_shared(sslSocket); #else - throw IoTDBException("SSL/TLS support is not enabled in this build. " - "Please rebuild with -DWITH_SSL=ON flag " - "or use non-SSL connection."); + throw IoTDBException("SSL/TLS support is not enabled in this build. " + "Please rebuild with -DWITH_SSL=ON flag " + "or use non-SSL connection."); #endif - } else { - auto socket = std::make_shared(endPoint.ip, endPoint.port); - socket->setConnTimeout(connectionTimeoutInMs); - transport = std::make_shared(socket); - } - if (!transport->isOpen()) { - try { - transport->open(); - } - catch (TTransportException& e) { - log_debug(e.what()); - throw IoTDBConnectionException(e.what()); - } - } - if (enableRPCCompression) { - shared_ptr protocol(new TCompactProtocol(transport)); - client = std::make_shared(protocol); - } - else { - shared_ptr protocol(new TBinaryProtocol(transport)); - client = std::make_shared(protocol); - } - - std::map configuration; - configuration["version"] = session->getVersionString(session->version); - configuration["sql_dialect"] = sqlDialect; - if (database != "") { - configuration["db"] = database; - } - TSOpenSessionReq openReq; - openReq.__set_username(session->username_); - openReq.__set_password(session->password_); - openReq.__set_zoneId(zoneId); - openReq.__set_configuration(configuration); + } else { + auto socket = std::make_shared(endPoint.ip, endPoint.port); + socket->setConnTimeout(connectionTimeoutInMs); + transport = std::make_shared(socket); + } + if (!transport->isOpen()) { try { - TSOpenSessionResp openResp; - client->openSession(openResp, openReq); - RpcUtils::verifySuccess(openResp.status); - if (session->protocolVersion_ != openResp.serverProtocolVersion) { - if (openResp.serverProtocolVersion == 0) { - // less than 0.10 - throw logic_error(string("Protocol not supported, Client version is ") + - to_string(session->protocolVersion_) + - ", but Server version is " + to_string(openResp.serverProtocolVersion)); - } - } - - sessionId = openResp.sessionId; - statementId = client->requestStatementId(sessionId); - - if (!zoneId.empty()) { - setTimeZone(zoneId); - } + transport->open(); + } catch (TTransportException& e) { + log_debug(e.what()); + throw IoTDBConnectionException(e.what()); } - catch (const TTransportException& e) { - log_debug(e.what()); - transport->close(); - throw IoTDBConnectionException(e.what()); - } catch (const IoTDBException& e) { - log_debug(e.what()); - transport->close(); - throw; - } catch (const exception& e) { - log_debug(e.what()); - transport->close(); - throw; + } + if (enableRPCCompression) { + shared_ptr protocol(new TCompactProtocol(transport)); + client = std::make_shared(protocol); + } else { + shared_ptr protocol(new TBinaryProtocol(transport)); + client = std::make_shared(protocol); + } + + std::map configuration; + configuration["version"] = session->getVersionString(session->version); + configuration["sql_dialect"] = sqlDialect; + if (database != "") { + configuration["db"] = database; + } + TSOpenSessionReq openReq; + openReq.__set_username(session->username_); + openReq.__set_password(session->password_); + openReq.__set_zoneId(zoneId); + openReq.__set_configuration(configuration); + try { + TSOpenSessionResp openResp; + client->openSession(openResp, openReq); + RpcUtils::verifySuccess(openResp.status); + if (session->protocolVersion_ != openResp.serverProtocolVersion) { + if (openResp.serverProtocolVersion == 0) { + // less than 0.10 + throw logic_error(string("Protocol not supported, Client version is ") + + to_string(session->protocolVersion_) + ", but Server version is " + + to_string(openResp.serverProtocolVersion)); + } } -} -std::unique_ptr SessionConnection::executeQueryStatement(const std::string& sql, int64_t timeoutInMs) { - TSExecuteStatementReq req; - req.__set_sessionId(sessionId); - req.__set_statementId(statementId); - req.__set_statement(sql); - req.__set_timeout(timeoutInMs); - req.__set_enableRedirectQuery(true); - - auto result = callWithRetryAndReconnect( - [this, &req]() { - TSExecuteStatementResp resp; - client->executeQueryStatementV2(resp, req); - return resp; - }, - [](const TSExecuteStatementResp& resp) { - return resp.status; - } - ); - TSExecuteStatementResp resp = result.getResult(); - if (result.getRetryAttempts() == 0) { - RpcUtils::verifySuccessWithRedirection(resp.status); - } - else { - RpcUtils::verifySuccess(resp.status); - } + sessionId = openResp.sessionId; + statementId = client->requestStatementId(sessionId); - return std::unique_ptr(new SessionDataSet(sql, resp.columns, resp.dataTypeList, - resp.columnNameIndexMap, resp.queryId, statementId, - client, sessionId, resp.queryResult, resp.ignoreTimeStamp, - timeoutInMs, resp.moreData, fetchSize, zoneId, - timeFactor, resp.columnIndex2TsBlockColumnIndexList)); -} - -std::unique_ptr SessionConnection::executeRawDataQuery(const std::vector& paths, - int64_t startTime, int64_t endTime) { - TSRawDataQueryReq req; - req.__set_sessionId(sessionId); - req.__set_statementId(statementId); - req.__set_fetchSize(fetchSize); - req.__set_paths(paths); - req.__set_startTime(startTime); - req.__set_endTime(endTime); - auto result = callWithRetryAndReconnect( - [this, &req]() { - TSExecuteStatementResp resp; - client->executeRawDataQueryV2(resp, req); - return resp; - }, - [](const TSExecuteStatementResp& resp) { - return resp.status; - } - ); - TSExecuteStatementResp resp = result.getResult(); - if (result.getRetryAttempts() == 0) { - RpcUtils::verifySuccessWithRedirection(resp.status); + if (!zoneId.empty()) { + setTimeZone(zoneId); } - else { - RpcUtils::verifySuccess(resp.status); - } - return std::unique_ptr(new SessionDataSet("", resp.columns, resp.dataTypeList, - resp.columnNameIndexMap, resp.queryId, statementId, - client, sessionId, resp.queryResult, resp.ignoreTimeStamp, - connectionTimeoutInMs, resp.moreData, fetchSize, zoneId, - timeFactor, resp.columnIndex2TsBlockColumnIndexList)); -} - -std::unique_ptr SessionConnection::executeLastDataQuery(const std::vector& paths, - int64_t lastTime) { - TSLastDataQueryReq req; - req.__set_sessionId(sessionId); - req.__set_statementId(statementId); - req.__set_fetchSize(fetchSize); - req.__set_paths(paths); - req.__set_time(lastTime); - - auto result = callWithRetryAndReconnect( - [this, &req]() { - TSExecuteStatementResp resp; - client->executeLastDataQuery(resp, req); - return resp; - }, - [](const TSExecuteStatementResp& resp) { - return resp.status; - } - ); - TSExecuteStatementResp resp = result.getResult(); - if (result.getRetryAttempts() == 0) { - RpcUtils::verifySuccessWithRedirection(resp.status); - } - else { - RpcUtils::verifySuccess(resp.status); - } - return std::unique_ptr(new SessionDataSet("", resp.columns, resp.dataTypeList, - resp.columnNameIndexMap, resp.queryId, statementId, - client, sessionId, resp.queryResult, resp.ignoreTimeStamp, - connectionTimeoutInMs, resp.moreData, fetchSize, zoneId, - timeFactor, resp.columnIndex2TsBlockColumnIndexList)); + } catch (const TTransportException& e) { + log_debug(e.what()); + transport->close(); + throw IoTDBConnectionException(e.what()); + } catch (const IoTDBException& e) { + log_debug(e.what()); + transport->close(); + throw; + } catch (const exception& e) { + log_debug(e.what()); + transport->close(); + throw; + } +} + +std::unique_ptr SessionConnection::executeQueryStatement(const std::string& sql, + int64_t timeoutInMs) { + TSExecuteStatementReq req; + req.__set_sessionId(sessionId); + req.__set_statementId(statementId); + req.__set_statement(sql); + req.__set_timeout(timeoutInMs); + req.__set_enableRedirectQuery(true); + + auto result = callWithRetryAndReconnect( + [this, &req]() { + TSExecuteStatementResp resp; + client->executeQueryStatementV2(resp, req); + return resp; + }, + [](const TSExecuteStatementResp& resp) { return resp.status; }); + TSExecuteStatementResp resp = result.getResult(); + if (result.getRetryAttempts() == 0) { + RpcUtils::verifySuccessWithRedirection(resp.status); + } else { + RpcUtils::verifySuccess(resp.status); + } + + return std::unique_ptr(new SessionDataSet( + sql, resp.columns, resp.dataTypeList, resp.columnNameIndexMap, resp.queryId, statementId, + client, sessionId, resp.queryResult, resp.ignoreTimeStamp, timeoutInMs, resp.moreData, + fetchSize, zoneId, timeFactor, resp.columnIndex2TsBlockColumnIndexList)); +} + +std::unique_ptr +SessionConnection::executeRawDataQuery(const std::vector& paths, int64_t startTime, + int64_t endTime) { + TSRawDataQueryReq req; + req.__set_sessionId(sessionId); + req.__set_statementId(statementId); + req.__set_fetchSize(fetchSize); + req.__set_paths(paths); + req.__set_startTime(startTime); + req.__set_endTime(endTime); + auto result = callWithRetryAndReconnect( + [this, &req]() { + TSExecuteStatementResp resp; + client->executeRawDataQueryV2(resp, req); + return resp; + }, + [](const TSExecuteStatementResp& resp) { return resp.status; }); + TSExecuteStatementResp resp = result.getResult(); + if (result.getRetryAttempts() == 0) { + RpcUtils::verifySuccessWithRedirection(resp.status); + } else { + RpcUtils::verifySuccess(resp.status); + } + return std::unique_ptr(new SessionDataSet( + "", resp.columns, resp.dataTypeList, resp.columnNameIndexMap, resp.queryId, statementId, + client, sessionId, resp.queryResult, resp.ignoreTimeStamp, connectionTimeoutInMs, + resp.moreData, fetchSize, zoneId, timeFactor, resp.columnIndex2TsBlockColumnIndexList)); +} + +std::unique_ptr +SessionConnection::executeLastDataQuery(const std::vector& paths, int64_t lastTime) { + TSLastDataQueryReq req; + req.__set_sessionId(sessionId); + req.__set_statementId(statementId); + req.__set_fetchSize(fetchSize); + req.__set_paths(paths); + req.__set_time(lastTime); + + auto result = callWithRetryAndReconnect( + [this, &req]() { + TSExecuteStatementResp resp; + client->executeLastDataQuery(resp, req); + return resp; + }, + [](const TSExecuteStatementResp& resp) { return resp.status; }); + TSExecuteStatementResp resp = result.getResult(); + if (result.getRetryAttempts() == 0) { + RpcUtils::verifySuccessWithRedirection(resp.status); + } else { + RpcUtils::verifySuccess(resp.status); + } + return std::unique_ptr(new SessionDataSet( + "", resp.columns, resp.dataTypeList, resp.columnNameIndexMap, resp.queryId, statementId, + client, sessionId, resp.queryResult, resp.ignoreTimeStamp, connectionTimeoutInMs, + resp.moreData, fetchSize, zoneId, timeFactor, resp.columnIndex2TsBlockColumnIndexList)); } void SessionConnection::executeNonQueryStatement(const string& sql) { - TSExecuteStatementReq req; - req.__set_sessionId(sessionId); - req.__set_statementId(statementId); - req.__set_statement(sql); - req.__set_timeout(0); //0 means no timeout. This value keep consistent to JAVA SDK. - TSExecuteStatementResp resp; - try { - client->executeUpdateStatementV2(resp, req); - if (resp.database != "") { - database = resp.database; - session->database_ = database; - } - RpcUtils::verifySuccess(resp.status); - } - catch (const TTransportException& e) { - log_debug(e.what()); - throw IoTDBConnectionException(e.what()); - } catch (const IoTDBException& e) { - log_debug(e.what()); - throw; - } catch (const exception& e) { - throw IoTDBException(e.what()); + TSExecuteStatementReq req; + req.__set_sessionId(sessionId); + req.__set_statementId(statementId); + req.__set_statement(sql); + req.__set_timeout(0); //0 means no timeout. This value keep consistent to JAVA SDK. + TSExecuteStatementResp resp; + try { + client->executeUpdateStatementV2(resp, req); + if (resp.database != "") { + database = resp.database; + session->database_ = database; } + RpcUtils::verifySuccess(resp.status); + } catch (const TTransportException& e) { + log_debug(e.what()); + throw IoTDBConnectionException(e.what()); + } catch (const IoTDBException& e) { + log_debug(e.what()); + throw; + } catch (const exception& e) { + throw IoTDBException(e.what()); + } } const TEndPoint& SessionConnection::getEndPoint() { - return endPoint; + return endPoint; } void SessionConnection::setTimeZone(const std::string& newZoneId) { - TSSetTimeZoneReq req; - req.__set_sessionId(sessionId); - req.__set_timeZone(newZoneId); + TSSetTimeZoneReq req; + req.__set_sessionId(sessionId); + req.__set_timeZone(newZoneId); - try { - TSStatus tsStatus; - client->setTimeZone(tsStatus, req); - zoneId = newZoneId; - } - catch (const TException& e) { - throw IoTDBConnectionException(e.what()); - } + try { + TSStatus tsStatus; + client->setTimeZone(tsStatus, req); + zoneId = newZoneId; + } catch (const TException& e) { + throw IoTDBConnectionException(e.what()); + } } std::string SessionConnection::getSystemDefaultZoneId() { - time_t ts = 0; - struct tm tmv{}; -#if defined(_WIN64) || defined (WIN32) || defined (_WIN32) - localtime_s(&tmv, &ts); + time_t ts = 0; + struct tm tmv {}; +#if defined(_WIN64) || defined(WIN32) || defined(_WIN32) + localtime_s(&tmv, &ts); #else - localtime_r(&ts, &tmv); + localtime_r(&ts, &tmv); #endif - char zoneStr[32]; - strftime(zoneStr, sizeof(zoneStr), "%z", &tmv); - return zoneStr; + char zoneStr[32]; + strftime(zoneStr, sizeof(zoneStr), "%z", &tmv); + return zoneStr; } bool SessionConnection::reconnect() { - bool reconnect = false; - for (int i = 1; i <= 3; i++) { - if (transport != nullptr) { - transport->close(); - endPointList = std::move(availableNodes->getEndPointList()); - int currHostIndex = rand() % endPointList.size(); - int tryHostNum = 0; - for (int j = currHostIndex; j < endPointList.size(); j++) { - if (tryHostNum == endPointList.size()) { - break; - } - this->endPoint = endPointList[j]; - if (j == endPointList.size() - 1) { - j = -1; - } - tryHostNum++; - try { - init(this->endPoint, this->session->useSSL_, this->session->trustCertFilePath_); - reconnect = true; - } - catch (const IoTDBConnectionException& e) { - log_warn("The current node may have been down, connection exception: %s", e.what()); - continue; - } catch (exception& e) { - log_warn("login in failed, because %s", e.what()); - } - break; - } + bool reconnect = false; + for (int i = 1; i <= 3; i++) { + if (transport != nullptr) { + transport->close(); + endPointList = std::move(availableNodes->getEndPointList()); + int currHostIndex = rand() % endPointList.size(); + int tryHostNum = 0; + for (int j = currHostIndex; j < endPointList.size(); j++) { + if (tryHostNum == endPointList.size()) { + break; } - if (reconnect) { - session->removeBrokenSessionConnection(shared_from_this()); - session->defaultEndPoint_ = this->endPoint; - session->defaultSessionConnection_ = shared_from_this(); - session->endPointToSessionConnection.insert(make_pair(this->endPoint, shared_from_this())); + this->endPoint = endPointList[j]; + if (j == endPointList.size() - 1) { + j = -1; } + tryHostNum++; + try { + init(this->endPoint, this->session->useSSL_, this->session->trustCertFilePath_); + reconnect = true; + } catch (const IoTDBConnectionException& e) { + log_warn("The current node may have been down, connection exception: %s", e.what()); + continue; + } catch (exception& e) { + log_warn("login in failed, because %s", e.what()); + } + break; + } } - return reconnect; + if (reconnect) { + session->removeBrokenSessionConnection(shared_from_this()); + session->defaultEndPoint_ = this->endPoint; + session->defaultSessionConnection_ = shared_from_this(); + session->endPointToSessionConnection.insert(make_pair(this->endPoint, shared_from_this())); + } + } + return reconnect; } void SessionConnection::insertStringRecord(const TSInsertStringRecordReq& request) { - auto rpc = [this, request]() { - return this->insertStringRecordInternal(request); - }; - callWithRetryAndVerifyWithRedirection(rpc); + auto rpc = [this, request]() { return this->insertStringRecordInternal(request); }; + callWithRetryAndVerifyWithRedirection(rpc); } void SessionConnection::insertRecord(const TSInsertRecordReq& request) { - auto rpc = [this, request]() { - return this->insertRecordInternal(request); - }; - callWithRetryAndVerifyWithRedirection(rpc); + auto rpc = [this, request]() { return this->insertRecordInternal(request); }; + callWithRetryAndVerifyWithRedirection(rpc); } void SessionConnection::insertStringRecords(const TSInsertStringRecordsReq& request) { - auto rpc = [this, request]() { - return this->insertStringRecordsInternal(request); - }; - callWithRetryAndVerifyWithRedirection(rpc); + auto rpc = [this, request]() { return this->insertStringRecordsInternal(request); }; + callWithRetryAndVerifyWithRedirection(rpc); } void SessionConnection::insertRecords(const TSInsertRecordsReq& request) { - auto rpc = [this, request]() { - return this->insertRecordsInternal(request); - }; - callWithRetryAndVerifyWithRedirection(rpc); + auto rpc = [this, request]() { return this->insertRecordsInternal(request); }; + callWithRetryAndVerifyWithRedirection(rpc); } void SessionConnection::insertRecordsOfOneDevice(TSInsertRecordsOfOneDeviceReq request) { - auto rpc = [this, request]() { - return this->insertRecordsOfOneDeviceInternal(request); - }; - callWithRetryAndVerifyWithRedirection(rpc); + auto rpc = [this, request]() { return this->insertRecordsOfOneDeviceInternal(request); }; + callWithRetryAndVerifyWithRedirection(rpc); } -void SessionConnection::insertStringRecordsOfOneDevice(TSInsertStringRecordsOfOneDeviceReq request) { - auto rpc = [this, request]() { - return this->insertStringRecordsOfOneDeviceInternal(request); - }; - callWithRetryAndVerifyWithRedirection(rpc); +void SessionConnection::insertStringRecordsOfOneDevice( + TSInsertStringRecordsOfOneDeviceReq request) { + auto rpc = [this, request]() { return this->insertStringRecordsOfOneDeviceInternal(request); }; + callWithRetryAndVerifyWithRedirection(rpc); } void SessionConnection::insertTablet(TSInsertTabletReq request) { - auto rpc = [this, request]() { - return this->insertTabletInternal(request); - }; - callWithRetryAndVerifyWithRedirection(rpc); + auto rpc = [this, request]() { return this->insertTabletInternal(request); }; + callWithRetryAndVerifyWithRedirection(rpc); } void SessionConnection::insertTablets(TSInsertTabletsReq request) { - auto rpc = [this, request]() { - return this->insertTabletsInternal(request); - }; - callWithRetryAndVerifyWithRedirection(rpc); + auto rpc = [this, request]() { return this->insertTabletsInternal(request); }; + callWithRetryAndVerifyWithRedirection(rpc); } void SessionConnection::testInsertStringRecord(TSInsertStringRecordReq& request) { - auto rpc = [this, &request]() { - request.sessionId = sessionId; - TSStatus ret; - client->testInsertStringRecord(ret, request); - return ret; - }; - auto status = callWithRetryAndReconnect(rpc).getResult(); - RpcUtils::verifySuccess(status); + auto rpc = [this, &request]() { + request.sessionId = sessionId; + TSStatus ret; + client->testInsertStringRecord(ret, request); + return ret; + }; + auto status = callWithRetryAndReconnect(rpc).getResult(); + RpcUtils::verifySuccess(status); } void SessionConnection::testInsertTablet(TSInsertTabletReq& request) { - auto rpc = [this, &request]() { - request.sessionId = sessionId; - TSStatus ret; - client->testInsertTablet(ret, request); - return ret; - }; - auto status = callWithRetryAndReconnect(rpc).getResult(); - RpcUtils::verifySuccess(status); + auto rpc = [this, &request]() { + request.sessionId = sessionId; + TSStatus ret; + client->testInsertTablet(ret, request); + return ret; + }; + auto status = callWithRetryAndReconnect(rpc).getResult(); + RpcUtils::verifySuccess(status); } void SessionConnection::testInsertRecords(TSInsertRecordsReq& request) { - auto rpc = [this, &request]() { - request.sessionId = sessionId; - TSStatus ret; - client->testInsertRecords(ret, request); - return ret; - }; - auto status = callWithRetryAndReconnect(rpc).getResult(); - RpcUtils::verifySuccess(status); + auto rpc = [this, &request]() { + request.sessionId = sessionId; + TSStatus ret; + client->testInsertRecords(ret, request); + return ret; + }; + auto status = callWithRetryAndReconnect(rpc).getResult(); + RpcUtils::verifySuccess(status); } void SessionConnection::deleteTimeseries(const vector& paths) { - auto rpc = [this, &paths]() { - TSStatus ret; - client->deleteTimeseries(ret, sessionId, paths); - return ret; - }; - callWithRetryAndVerify(rpc); + auto rpc = [this, &paths]() { + TSStatus ret; + client->deleteTimeseries(ret, sessionId, paths); + return ret; + }; + callWithRetryAndVerify(rpc); } void SessionConnection::deleteData(const TSDeleteDataReq& request) { - auto rpc = [this, request]() { - return this->deleteDataInternal(request); - }; - callWithRetryAndVerify(rpc); + auto rpc = [this, request]() { return this->deleteDataInternal(request); }; + callWithRetryAndVerify(rpc); } void SessionConnection::setStorageGroup(const string& storageGroupId) { - auto rpc = [this, &storageGroupId]() { - TSStatus ret; - client->setStorageGroup(ret, sessionId, storageGroupId); - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc); - RpcUtils::verifySuccess(ret.getResult()); + auto rpc = [this, &storageGroupId]() { + TSStatus ret; + client->setStorageGroup(ret, sessionId, storageGroupId); + return ret; + }; + auto ret = callWithRetryAndReconnect(rpc); + RpcUtils::verifySuccess(ret.getResult()); } void SessionConnection::deleteStorageGroups(const vector& storageGroups) { - auto rpc = [this, &storageGroups]() { - TSStatus ret; - client->deleteStorageGroups(ret, sessionId, storageGroups); - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc); - RpcUtils::verifySuccess(ret.getResult()); + auto rpc = [this, &storageGroups]() { + TSStatus ret; + client->deleteStorageGroups(ret, sessionId, storageGroups); + return ret; + }; + auto ret = callWithRetryAndReconnect(rpc); + RpcUtils::verifySuccess(ret.getResult()); } void SessionConnection::createTimeseries(TSCreateTimeseriesReq& req) { - auto rpc = [this, &req]() { - TSStatus ret; - req.sessionId = sessionId; - client->createTimeseries(ret, req); - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc); - RpcUtils::verifySuccess(ret.getResult()); + auto rpc = [this, &req]() { + TSStatus ret; + req.sessionId = sessionId; + client->createTimeseries(ret, req); + return ret; + }; + auto ret = callWithRetryAndReconnect(rpc); + RpcUtils::verifySuccess(ret.getResult()); } void SessionConnection::createMultiTimeseries(TSCreateMultiTimeseriesReq& req) { - auto rpc = [this, &req]() { - TSStatus ret; - req.sessionId = sessionId; - client->createMultiTimeseries(ret, req); - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc); - RpcUtils::verifySuccess(ret.getResult()); + auto rpc = [this, &req]() { + TSStatus ret; + req.sessionId = sessionId; + client->createMultiTimeseries(ret, req); + return ret; + }; + auto ret = callWithRetryAndReconnect(rpc); + RpcUtils::verifySuccess(ret.getResult()); } void SessionConnection::createAlignedTimeseries(TSCreateAlignedTimeseriesReq& req) { - auto rpc = [this, &req]() { - TSStatus ret; - req.sessionId = sessionId; - client->createAlignedTimeseries(ret, req); - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc); - RpcUtils::verifySuccess(ret.getResult()); + auto rpc = [this, &req]() { + TSStatus ret; + req.sessionId = sessionId; + client->createAlignedTimeseries(ret, req); + return ret; + }; + auto ret = callWithRetryAndReconnect(rpc); + RpcUtils::verifySuccess(ret.getResult()); } TSGetTimeZoneResp SessionConnection::getTimeZone() { - auto rpc = [this]() { - TSGetTimeZoneResp resp; - client->getTimeZone(resp, sessionId); - zoneId = resp.timeZone; - return resp; - }; - auto ret = callWithRetryAndReconnect(rpc, - [](const TSGetTimeZoneResp& resp) { - return resp.status; - }); - RpcUtils::verifySuccess(ret.getResult().status); - return ret.result; + auto rpc = [this]() { + TSGetTimeZoneResp resp; + client->getTimeZone(resp, sessionId); + zoneId = resp.timeZone; + return resp; + }; + auto ret = callWithRetryAndReconnect( + rpc, [](const TSGetTimeZoneResp& resp) { return resp.status; }); + RpcUtils::verifySuccess(ret.getResult().status); + return ret.result; } void SessionConnection::setTimeZone(TSSetTimeZoneReq& req) { - auto rpc = [this, &req]() { - TSStatus ret; - req.sessionId = sessionId; - client->setTimeZone(ret, req); - zoneId = req.timeZone; - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc); - RpcUtils::verifySuccess(ret.getResult()); + auto rpc = [this, &req]() { + TSStatus ret; + req.sessionId = sessionId; + client->setTimeZone(ret, req); + zoneId = req.timeZone; + return ret; + }; + auto ret = callWithRetryAndReconnect(rpc); + RpcUtils::verifySuccess(ret.getResult()); } void SessionConnection::createSchemaTemplate(TSCreateSchemaTemplateReq req) { - auto rpc = [this, &req]() { - TSStatus ret; - req.sessionId = sessionId; - client->createSchemaTemplate(ret, req); - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc); - RpcUtils::verifySuccess(ret.getResult()); + auto rpc = [this, &req]() { + TSStatus ret; + req.sessionId = sessionId; + client->createSchemaTemplate(ret, req); + return ret; + }; + auto ret = callWithRetryAndReconnect(rpc); + RpcUtils::verifySuccess(ret.getResult()); } void SessionConnection::setSchemaTemplate(TSSetSchemaTemplateReq req) { - auto rpc = [this, &req]() { - TSStatus ret; - req.sessionId = sessionId; - client->setSchemaTemplate(ret, req); - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc); - RpcUtils::verifySuccess(ret.getResult()); + auto rpc = [this, &req]() { + TSStatus ret; + req.sessionId = sessionId; + client->setSchemaTemplate(ret, req); + return ret; + }; + auto ret = callWithRetryAndReconnect(rpc); + RpcUtils::verifySuccess(ret.getResult()); } void SessionConnection::unsetSchemaTemplate(TSUnsetSchemaTemplateReq req) { - auto rpc = [this, &req]() { - TSStatus ret; - req.sessionId = sessionId; - client->unsetSchemaTemplate(ret, req); - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc); - RpcUtils::verifySuccess(ret.getResult()); + auto rpc = [this, &req]() { + TSStatus ret; + req.sessionId = sessionId; + client->unsetSchemaTemplate(ret, req); + return ret; + }; + auto ret = callWithRetryAndReconnect(rpc); + RpcUtils::verifySuccess(ret.getResult()); } void SessionConnection::appendSchemaTemplate(TSAppendSchemaTemplateReq req) { - auto rpc = [this, &req]() { - TSStatus ret; - req.sessionId = sessionId; - client->appendSchemaTemplate(ret, req); - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc); - RpcUtils::verifySuccess(ret.getResult()); + auto rpc = [this, &req]() { + TSStatus ret; + req.sessionId = sessionId; + client->appendSchemaTemplate(ret, req); + return ret; + }; + auto ret = callWithRetryAndReconnect(rpc); + RpcUtils::verifySuccess(ret.getResult()); } void SessionConnection::pruneSchemaTemplate(TSPruneSchemaTemplateReq req) { - auto rpc = [this, &req]() { - TSStatus ret; - req.sessionId = sessionId; - client->pruneSchemaTemplate(ret, req); - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc); - RpcUtils::verifySuccess(ret.getResult()); + auto rpc = [this, &req]() { + TSStatus ret; + req.sessionId = sessionId; + client->pruneSchemaTemplate(ret, req); + return ret; + }; + auto ret = callWithRetryAndReconnect(rpc); + RpcUtils::verifySuccess(ret.getResult()); } TSQueryTemplateResp SessionConnection::querySchemaTemplate(TSQueryTemplateReq req) { - auto rpc = [this, &req]() { - TSQueryTemplateResp ret; - req.sessionId = sessionId; - client->querySchemaTemplate(ret, req); - return ret; - }; - auto ret = callWithRetryAndReconnect(rpc, - [](const TSQueryTemplateResp& resp) { - return resp.status; - }); - RpcUtils::verifySuccess(ret.getResult().status); - return ret.getResult(); + auto rpc = [this, &req]() { + TSQueryTemplateResp ret; + req.sessionId = sessionId; + client->querySchemaTemplate(ret, req); + return ret; + }; + auto ret = callWithRetryAndReconnect( + rpc, [](const TSQueryTemplateResp& resp) { return resp.status; }); + RpcUtils::verifySuccess(ret.getResult().status); + return ret.getResult(); } TSStatus SessionConnection::insertStringRecordInternal(TSInsertStringRecordReq request) { - request.sessionId = sessionId; - TSStatus ret; - client->insertStringRecord(ret, request); - return ret; + request.sessionId = sessionId; + TSStatus ret; + client->insertStringRecord(ret, request); + return ret; } TSStatus SessionConnection::insertRecordInternal(TSInsertRecordReq request) { - request.sessionId = sessionId; - TSStatus ret; - client->insertRecord(ret, request); - return ret; + request.sessionId = sessionId; + TSStatus ret; + client->insertRecord(ret, request); + return ret; } TSStatus SessionConnection::insertStringRecordsInternal(TSInsertStringRecordsReq request) { - request.sessionId = sessionId; - TSStatus ret; - client->insertStringRecords(ret, request); - return ret; + request.sessionId = sessionId; + TSStatus ret; + client->insertStringRecords(ret, request); + return ret; } TSStatus SessionConnection::insertRecordsInternal(TSInsertRecordsReq request) { - request.sessionId = sessionId; - TSStatus ret; - client->insertRecords(ret, request); - return ret; + request.sessionId = sessionId; + TSStatus ret; + client->insertRecords(ret, request); + return ret; } -TSStatus SessionConnection::insertRecordsOfOneDeviceInternal(TSInsertRecordsOfOneDeviceReq request) { - request.sessionId = sessionId; - TSStatus ret; - client->insertRecordsOfOneDevice(ret, request); - return ret; +TSStatus +SessionConnection::insertRecordsOfOneDeviceInternal(TSInsertRecordsOfOneDeviceReq request) { + request.sessionId = sessionId; + TSStatus ret; + client->insertRecordsOfOneDevice(ret, request); + return ret; } -TSStatus SessionConnection::insertStringRecordsOfOneDeviceInternal(TSInsertStringRecordsOfOneDeviceReq request) { - request.sessionId = sessionId; - TSStatus ret; - client->insertStringRecordsOfOneDevice(ret, request); - return ret; +TSStatus SessionConnection::insertStringRecordsOfOneDeviceInternal( + TSInsertStringRecordsOfOneDeviceReq request) { + request.sessionId = sessionId; + TSStatus ret; + client->insertStringRecordsOfOneDevice(ret, request); + return ret; } TSStatus SessionConnection::insertTabletInternal(TSInsertTabletReq request) { - request.sessionId = sessionId; - TSStatus ret; - client->insertTablet(ret, request); - return ret; + request.sessionId = sessionId; + TSStatus ret; + client->insertTablet(ret, request); + return ret; } TSStatus SessionConnection::insertTabletsInternal(TSInsertTabletsReq request) { - request.sessionId = sessionId; - TSStatus ret; - client->insertTablets(ret, request); - return ret; + request.sessionId = sessionId; + TSStatus ret; + client->insertTablets(ret, request); + return ret; } TSStatus SessionConnection::deleteDataInternal(TSDeleteDataReq request) { - request.sessionId = sessionId; - TSStatus ret; - client->deleteData(ret, request); - return ret; + request.sessionId = sessionId; + TSStatus ret; + client->deleteData(ret, request); + return ret; } diff --git a/iotdb-client/client-cpp/src/main/SessionConnection.h b/iotdb-client/client-cpp/src/main/SessionConnection.h index a4ef7a7d64c48..031b7d3a8926f 100644 --- a/iotdb-client/client-cpp/src/main/SessionConnection.h +++ b/iotdb-client/client-cpp/src/main/SessionConnection.h @@ -37,336 +37,320 @@ class Session; class SessionConnection : public std::enable_shared_from_this { public: - SessionConnection(Session* session_ptr, const TEndPoint& endpoint, - const std::string& zoneId, - std::shared_ptr nodeSupplier, - int fetchSize = 10000, - int maxRetries = 3, - int64_t retryInterval = 500, - int64_t connectionTimeoutMs = 3 * 1000, - std::string dialect = "tree", - std::string db = ""); + SessionConnection(Session* session_ptr, const TEndPoint& endpoint, const std::string& zoneId, + std::shared_ptr nodeSupplier, int fetchSize = 10000, + int maxRetries = 3, int64_t retryInterval = 500, + int64_t connectionTimeoutMs = 3 * 1000, std::string dialect = "tree", + std::string db = ""); - ~SessionConnection(); + ~SessionConnection(); - void setTimeZone(const std::string& newZoneId); + void setTimeZone(const std::string& newZoneId); + const TEndPoint& getEndPoint(); - const TEndPoint& getEndPoint(); + void init(const TEndPoint& endpoint, bool useSSL, const std::string& trustCertFilePath); - void init(const TEndPoint& endpoint, bool useSSL, const std::string& trustCertFilePath); + void insertStringRecord(const TSInsertStringRecordReq& request); - void insertStringRecord(const TSInsertStringRecordReq& request); + void insertRecord(const TSInsertRecordReq& request); - void insertRecord(const TSInsertRecordReq& request); + void insertStringRecords(const TSInsertStringRecordsReq& request); - void insertStringRecords(const TSInsertStringRecordsReq& request); + void insertRecords(const TSInsertRecordsReq& request); - void insertRecords(const TSInsertRecordsReq& request); + void insertRecordsOfOneDevice(TSInsertRecordsOfOneDeviceReq request); - void insertRecordsOfOneDevice(TSInsertRecordsOfOneDeviceReq request); + void insertStringRecordsOfOneDevice(TSInsertStringRecordsOfOneDeviceReq request); - void insertStringRecordsOfOneDevice(TSInsertStringRecordsOfOneDeviceReq request); + void insertTablet(TSInsertTabletReq request); - void insertTablet(TSInsertTabletReq request); + void insertTablets(TSInsertTabletsReq request); - void insertTablets(TSInsertTabletsReq request); + void testInsertStringRecord(TSInsertStringRecordReq& request); - void testInsertStringRecord(TSInsertStringRecordReq& request); + void testInsertTablet(TSInsertTabletReq& request); - void testInsertTablet(TSInsertTabletReq& request); + void testInsertRecords(TSInsertRecordsReq& request); - void testInsertRecords(TSInsertRecordsReq& request); + void deleteTimeseries(const vector& paths); - void deleteTimeseries(const vector& paths); + void deleteData(const TSDeleteDataReq& request); - void deleteData(const TSDeleteDataReq& request); + void setStorageGroup(const string& storageGroupId); - void setStorageGroup(const string& storageGroupId); + void deleteStorageGroups(const vector& storageGroups); - void deleteStorageGroups(const vector& storageGroups); + void createTimeseries(TSCreateTimeseriesReq& req); - void createTimeseries(TSCreateTimeseriesReq& req); + void createMultiTimeseries(TSCreateMultiTimeseriesReq& req); - void createMultiTimeseries(TSCreateMultiTimeseriesReq& req); + void createAlignedTimeseries(TSCreateAlignedTimeseriesReq& req); - void createAlignedTimeseries(TSCreateAlignedTimeseriesReq& req); + TSGetTimeZoneResp getTimeZone(); - TSGetTimeZoneResp getTimeZone(); + void setTimeZone(TSSetTimeZoneReq& req); - void setTimeZone(TSSetTimeZoneReq& req); + void createSchemaTemplate(TSCreateSchemaTemplateReq req); - void createSchemaTemplate(TSCreateSchemaTemplateReq req); + void setSchemaTemplate(TSSetSchemaTemplateReq req); - void setSchemaTemplate(TSSetSchemaTemplateReq req); + void unsetSchemaTemplate(TSUnsetSchemaTemplateReq req); - void unsetSchemaTemplate(TSUnsetSchemaTemplateReq req); + void appendSchemaTemplate(TSAppendSchemaTemplateReq req); - void appendSchemaTemplate(TSAppendSchemaTemplateReq req); + void pruneSchemaTemplate(TSPruneSchemaTemplateReq req); - void pruneSchemaTemplate(TSPruneSchemaTemplateReq req); + TSQueryTemplateResp querySchemaTemplate(TSQueryTemplateReq req); - TSQueryTemplateResp querySchemaTemplate(TSQueryTemplateReq req); + std::unique_ptr executeRawDataQuery(const std::vector& paths, + int64_t startTime, int64_t endTime); - std::unique_ptr executeRawDataQuery(const std::vector& paths, int64_t startTime, - int64_t endTime); + std::unique_ptr executeLastDataQuery(const std::vector& paths, + int64_t lastTime); - std::unique_ptr executeLastDataQuery(const std::vector& paths, int64_t lastTime); + void executeNonQueryStatement(const std::string& sql); - void executeNonQueryStatement(const std::string& sql); + std::unique_ptr executeQueryStatement(const std::string& sql, + int64_t timeoutInMs = -1); - std::unique_ptr executeQueryStatement(const std::string& sql, int64_t timeoutInMs = -1); + std::shared_ptr getSessionClient() { + return client; + } - std::shared_ptr getSessionClient() { - return client; - } - - friend class Session; + friend class Session; private: - void close(); - std::string getSystemDefaultZoneId(); - bool reconnect(); + void close(); + std::string getSystemDefaultZoneId(); + bool reconnect(); - template - struct RetryResult { - T result; - std::exception_ptr exception; - int retryAttempts; + template struct RetryResult { + T result; + std::exception_ptr exception; + int retryAttempts; - RetryResult(T r, std::exception_ptr e, int a) - : result(r), exception(e), retryAttempts(a) { - } + RetryResult(T r, std::exception_ptr e, int a) : result(r), exception(e), retryAttempts(a) {} - int getRetryAttempts() const { return retryAttempts; } - T getResult() const { return result; } - std::exception_ptr getException() const { return exception; } - }; + int getRetryAttempts() const { + return retryAttempts; + } + T getResult() const { + return result; + } + std::exception_ptr getException() const { + return exception; + } + }; - template - void callWithRetryAndVerifyWithRedirection(std::function rpc); + template void callWithRetryAndVerifyWithRedirection(std::function rpc); - template - void callWithRetryAndVerifyWithRedirectionForMultipleDevices( - std::function rpc, const vector& deviceIds); + template + void callWithRetryAndVerifyWithRedirectionForMultipleDevices(std::function rpc, + const vector& deviceIds); - template - RetryResult callWithRetryAndVerify(std::function rpc); + template RetryResult callWithRetryAndVerify(std::function rpc); - template - RetryResult callWithRetry(std::function rpc); + template RetryResult callWithRetry(std::function rpc); - template - RetryResult callWithRetryAndReconnect(RpcFunc rpc); + template RetryResult callWithRetryAndReconnect(RpcFunc rpc); - template - RetryResult callWithRetryAndReconnect(RpcFunc rpc, StatusGetter statusGetter); + template + RetryResult callWithRetryAndReconnect(RpcFunc rpc, StatusGetter statusGetter); - template - RetryResult callWithRetryAndReconnect(RpcFunc rpc, ShouldRetry shouldRetry, ForceReconnect forceReconnect); + template + RetryResult callWithRetryAndReconnect(RpcFunc rpc, ShouldRetry shouldRetry, + ForceReconnect forceReconnect); - TSStatus insertStringRecordInternal(TSInsertStringRecordReq request); + TSStatus insertStringRecordInternal(TSInsertStringRecordReq request); - TSStatus insertRecordInternal(TSInsertRecordReq request); + TSStatus insertRecordInternal(TSInsertRecordReq request); - TSStatus insertStringRecordsInternal(TSInsertStringRecordsReq request); + TSStatus insertStringRecordsInternal(TSInsertStringRecordsReq request); - TSStatus insertRecordsInternal(TSInsertRecordsReq request); + TSStatus insertRecordsInternal(TSInsertRecordsReq request); - TSStatus insertRecordsOfOneDeviceInternal(TSInsertRecordsOfOneDeviceReq request); + TSStatus insertRecordsOfOneDeviceInternal(TSInsertRecordsOfOneDeviceReq request); - TSStatus insertStringRecordsOfOneDeviceInternal(TSInsertStringRecordsOfOneDeviceReq request); + TSStatus insertStringRecordsOfOneDeviceInternal(TSInsertStringRecordsOfOneDeviceReq request); - TSStatus insertTabletInternal(TSInsertTabletReq request); + TSStatus insertTabletInternal(TSInsertTabletReq request); - TSStatus insertTabletsInternal(TSInsertTabletsReq request); + TSStatus insertTabletsInternal(TSInsertTabletsReq request); - TSStatus deleteDataInternal(TSDeleteDataReq request); + TSStatus deleteDataInternal(TSDeleteDataReq request); #if WITH_SSL - std::shared_ptr socketFactory_ = - std::make_shared(); + std::shared_ptr socketFactory_ = + std::make_shared(); #endif - std::shared_ptr transport; - std::shared_ptr client; - Session* session; - int64_t sessionId; - int64_t statementId; - int64_t connectionTimeoutInMs; - bool enableRPCCompression = false; - std::string zoneId; - TEndPoint endPoint; - std::vector endPointList; - std::shared_ptr availableNodes; - int fetchSize; - int maxRetryCount; - int64_t retryIntervalMs; - std::string sqlDialect; - std::string database; - int timeFactor = 1000; + std::shared_ptr transport; + std::shared_ptr client; + Session* session; + int64_t sessionId; + int64_t statementId; + int64_t connectionTimeoutInMs; + bool enableRPCCompression = false; + std::string zoneId; + TEndPoint endPoint; + std::vector endPointList; + std::shared_ptr availableNodes; + int fetchSize; + int maxRetryCount; + int64_t retryIntervalMs; + std::string sqlDialect; + std::string database; + int timeFactor = 1000; }; template SessionConnection::RetryResult SessionConnection::callWithRetry(std::function rpc) { - std::exception_ptr lastException = nullptr; - TSStatus status; - int i; - for (i = 0; i <= maxRetryCount; i++) { - if (i > 0) { - lastException = nullptr; - status = TSStatus(); - try { - std::this_thread::sleep_for( - std::chrono::milliseconds(retryIntervalMs)); - } - catch (const std::exception& e) { - break; - } - if (!reconnect()) { - continue; - } - } - - try { - status = rpc(); - if (status.__isset.needRetry && status.needRetry) { - continue; - } - break; - } - catch (...) { - lastException = std::current_exception(); - } + std::exception_ptr lastException = nullptr; + TSStatus status; + int i; + for (i = 0; i <= maxRetryCount; i++) { + if (i > 0) { + lastException = nullptr; + status = TSStatus(); + try { + std::this_thread::sleep_for(std::chrono::milliseconds(retryIntervalMs)); + } catch (const std::exception& e) { + break; + } + if (!reconnect()) { + continue; + } } - return {status, lastException, i}; + + try { + status = rpc(); + if (status.__isset.needRetry && status.needRetry) { + continue; + } + break; + } catch (...) { + lastException = std::current_exception(); + } + } + return {status, lastException, i}; } template void SessionConnection::callWithRetryAndVerifyWithRedirection(std::function rpc) { - auto result = callWithRetry(rpc); - - auto status = result.getResult(); - if (result.getRetryAttempts() == 0) { - RpcUtils::verifySuccessWithRedirection(status); - } - else { - RpcUtils::verifySuccess(status); - } - - if (result.getException()) { - try { - std::rethrow_exception(result.getException()); - } - catch (const std::exception& e) { - throw IoTDBConnectionException(e.what()); - } + auto result = callWithRetry(rpc); + + auto status = result.getResult(); + if (result.getRetryAttempts() == 0) { + RpcUtils::verifySuccessWithRedirection(status); + } else { + RpcUtils::verifySuccess(status); + } + + if (result.getException()) { + try { + std::rethrow_exception(result.getException()); + } catch (const std::exception& e) { + throw IoTDBConnectionException(e.what()); } + } } template void SessionConnection::callWithRetryAndVerifyWithRedirectionForMultipleDevices( std::function rpc, const vector& deviceIds) { - auto result = callWithRetry(rpc); - auto status = result.getResult(); - if (result.getRetryAttempts() == 0) { - RpcUtils::verifySuccessWithRedirectionForMultiDevices(status, deviceIds); - } - else { - RpcUtils::verifySuccess(status); - } - if (result.getException()) { - try { - std::rethrow_exception(result.getException()); - } - catch (const std::exception& e) { - throw IoTDBConnectionException(e.what()); - } + auto result = callWithRetry(rpc); + auto status = result.getResult(); + if (result.getRetryAttempts() == 0) { + RpcUtils::verifySuccessWithRedirectionForMultiDevices(status, deviceIds); + } else { + RpcUtils::verifySuccess(status); + } + if (result.getException()) { + try { + std::rethrow_exception(result.getException()); + } catch (const std::exception& e) { + throw IoTDBConnectionException(e.what()); } - result.exception = nullptr; + } + result.exception = nullptr; } template -SessionConnection::RetryResult SessionConnection::callWithRetryAndVerify(std::function rpc) { - auto result = callWithRetry(rpc); - RpcUtils::verifySuccess(result.getResult()); - if (result.getException()) { - try { - std::rethrow_exception(result.getException()); - } - catch (const std::exception& e) { - throw IoTDBConnectionException(e.what()); - } +SessionConnection::RetryResult +SessionConnection::callWithRetryAndVerify(std::function rpc) { + auto result = callWithRetry(rpc); + RpcUtils::verifySuccess(result.getResult()); + if (result.getException()) { + try { + std::rethrow_exception(result.getException()); + } catch (const std::exception& e) { + throw IoTDBConnectionException(e.what()); } - return result; + } + return result; } template SessionConnection::RetryResult SessionConnection::callWithRetryAndReconnect(RpcFunc rpc) { - return callWithRetryAndReconnect(rpc, - [](const TSStatus& status) { - return status.__isset.needRetry && status.needRetry; - }, - [](const TSStatus& status) { - return status.code == TSStatusCode::PLAN_FAILED_NETWORK_PARTITION; - } - ); + return callWithRetryAndReconnect( + rpc, [](const TSStatus& status) { return status.__isset.needRetry && status.needRetry; }, + [](const TSStatus& status) { + return status.code == TSStatusCode::PLAN_FAILED_NETWORK_PARTITION; + }); } template -SessionConnection::RetryResult SessionConnection::callWithRetryAndReconnect(RpcFunc rpc, StatusGetter statusGetter) { - auto shouldRetry = [&statusGetter](const T& t) { - auto status = statusGetter(t); - return status.__isset.needRetry && status.needRetry; - }; - auto forceReconnect = [&statusGetter](const T& t) { - auto status = statusGetter(t); - return status.code == TSStatusCode::PLAN_FAILED_NETWORK_PARTITION;; - }; - return callWithRetryAndReconnect(rpc, shouldRetry, forceReconnect); +SessionConnection::RetryResult +SessionConnection::callWithRetryAndReconnect(RpcFunc rpc, StatusGetter statusGetter) { + auto shouldRetry = [&statusGetter](const T& t) { + auto status = statusGetter(t); + return status.__isset.needRetry && status.needRetry; + }; + auto forceReconnect = [&statusGetter](const T& t) { + auto status = statusGetter(t); + return status.code == TSStatusCode::PLAN_FAILED_NETWORK_PARTITION; + ; + }; + return callWithRetryAndReconnect(rpc, shouldRetry, forceReconnect); } - template -SessionConnection::RetryResult SessionConnection::callWithRetryAndReconnect(RpcFunc rpc, - ShouldRetry shouldRetry, - ForceReconnect forceReconnect) { - std::exception_ptr lastException = nullptr; - T result; - int retryAttempt; - for (retryAttempt = 0; retryAttempt <= maxRetryCount; retryAttempt++) { - try { - result = rpc(); - lastException = nullptr; - } - catch (...) { - result = T(); - lastException = std::current_exception(); - } - - if (!shouldRetry(result)) { - return {result, lastException, retryAttempt}; - } - - if (lastException != nullptr || - std::find(availableNodes->getEndPointList().begin(), availableNodes->getEndPointList().end(), - this->endPoint) == availableNodes->getEndPointList().end() || - forceReconnect(result)) { - reconnect(); - } - - try { - std::this_thread::sleep_for(std::chrono::milliseconds(retryIntervalMs)); - } - catch (const std::exception& e) { - log_debug("Thread was interrupted during retry " + - std::to_string(retryAttempt) + - " with wait time " + - std::to_string(retryIntervalMs) + - " ms. Exiting retry loop."); - break; - } +SessionConnection::RetryResult +SessionConnection::callWithRetryAndReconnect(RpcFunc rpc, ShouldRetry shouldRetry, + ForceReconnect forceReconnect) { + std::exception_ptr lastException = nullptr; + T result; + int retryAttempt; + for (retryAttempt = 0; retryAttempt <= maxRetryCount; retryAttempt++) { + try { + result = rpc(); + lastException = nullptr; + } catch (...) { + result = T(); + lastException = std::current_exception(); + } + + if (!shouldRetry(result)) { + return {result, lastException, retryAttempt}; + } + + if (lastException != nullptr || + std::find(availableNodes->getEndPointList().begin(), + availableNodes->getEndPointList().end(), + this->endPoint) == availableNodes->getEndPointList().end() || + forceReconnect(result)) { + reconnect(); + } + + try { + std::this_thread::sleep_for(std::chrono::milliseconds(retryIntervalMs)); + } catch (const std::exception& e) { + log_debug("Thread was interrupted during retry " + std::to_string(retryAttempt) + + " with wait time " + std::to_string(retryIntervalMs) + " ms. Exiting retry loop."); + break; } + } - return {result, lastException, retryAttempt}; + return {result, lastException, retryAttempt}; } #endif diff --git a/iotdb-client/client-cpp/src/main/SessionDataSet.cpp b/iotdb-client/client-cpp/src/main/SessionDataSet.cpp index cf0ce63ff088e..11c2e8f528bd1 100644 --- a/iotdb-client/client-cpp/src/main/SessionDataSet.cpp +++ b/iotdb-client/client-cpp/src/main/SessionDataSet.cpp @@ -22,267 +22,268 @@ #include RowRecord::RowRecord(int64_t timestamp) { - this->timestamp = timestamp; + this->timestamp = timestamp; } RowRecord::RowRecord(int64_t timestamp, const std::vector& fields) - : timestamp(timestamp), fields(fields) { -} + : timestamp(timestamp), fields(fields) {} -RowRecord::RowRecord(const std::vector& fields) - : timestamp(-1), fields(fields) { -} +RowRecord::RowRecord(const std::vector& fields) : timestamp(-1), fields(fields) {} RowRecord::RowRecord() { - this->timestamp = -1; + this->timestamp = -1; } void RowRecord::addField(const Field& f) { - this->fields.push_back(f); + this->fields.push_back(f); } std::string RowRecord::toString() { - std::string ret; - if (this->timestamp != -1) { - ret.append(std::to_string(timestamp)); - ret.append("\t"); + std::string ret; + if (this->timestamp != -1) { + ret.append(std::to_string(timestamp)); + ret.append("\t"); + } + for (size_t i = 0; i < fields.size(); i++) { + if (i != 0) { + ret.append("\t"); } - for (size_t i = 0; i < fields.size(); i++) { - if (i != 0) { - ret.append("\t"); - } - const Field& f = fields[i]; - switch (f.dataType) { - case TSDataType::BOOLEAN: - if (f.isNull()) { - ret.append("null"); - } else { - ret.append(f.boolV.value() ? "true" : "false"); - } - break; - case TSDataType::INT32: - if (f.isNull()) { - ret.append("null"); - } else { - ret.append(std::to_string(f.intV.value())); - } - break; - case TSDataType::DATE: - if (f.isNull()) { - ret.append("null"); - } else { - ret.append(boost::gregorian::to_iso_extended_string(f.dateV.value())); - } - break; - case TSDataType::TIMESTAMP: - case TSDataType::INT64: - if (f.isNull()) { - ret.append("null"); - } else { - ret.append(std::to_string(f.longV.value())); - } - break; - case TSDataType::FLOAT: - if (f.isNull()) { - ret.append("null"); - } else { - ret.append(std::to_string(f.floatV.value())); - } - break; - case TSDataType::DOUBLE: - if (f.isNull()) { - ret.append("null"); - } else { - ret.append(std::to_string(f.doubleV.value())); - } - break; - case TSDataType::BLOB: - case TSDataType::STRING: - case TSDataType::TEXT: - if (f.isNull()) { - ret.append("null"); - } else { - ret.append(f.stringV.value()); - } - break; - case TSDataType::OBJECT: - if (!f.stringV.is_initialized()) { - ret.append("null"); - } else { - ret.append(f.stringV.value()); - } - break; - default: - break; - } + const Field& f = fields[i]; + switch (f.dataType) { + case TSDataType::BOOLEAN: + if (f.isNull()) { + ret.append("null"); + } else { + ret.append(f.boolV.value() ? "true" : "false"); + } + break; + case TSDataType::INT32: + if (f.isNull()) { + ret.append("null"); + } else { + ret.append(std::to_string(f.intV.value())); + } + break; + case TSDataType::DATE: + if (f.isNull()) { + ret.append("null"); + } else { + ret.append(boost::gregorian::to_iso_extended_string(f.dateV.value())); + } + break; + case TSDataType::TIMESTAMP: + case TSDataType::INT64: + if (f.isNull()) { + ret.append("null"); + } else { + ret.append(std::to_string(f.longV.value())); + } + break; + case TSDataType::FLOAT: + if (f.isNull()) { + ret.append("null"); + } else { + ret.append(std::to_string(f.floatV.value())); + } + break; + case TSDataType::DOUBLE: + if (f.isNull()) { + ret.append("null"); + } else { + ret.append(std::to_string(f.doubleV.value())); + } + break; + case TSDataType::BLOB: + case TSDataType::STRING: + case TSDataType::TEXT: + if (f.isNull()) { + ret.append("null"); + } else { + ret.append(f.stringV.value()); + } + break; + case TSDataType::OBJECT: + if (!f.stringV.is_initialized()) { + ret.append("null"); + } else { + ret.append(f.stringV.value()); + } + break; + default: + break; } - ret.append("\n"); - return ret; + } + ret.append("\n"); + return ret; } bool SessionDataSet::hasNext() { - if (iotdbRpcDataSet_->hasCachedRecord()) { - return true; - } - return iotdbRpcDataSet_->next(); + if (iotdbRpcDataSet_->hasCachedRecord()) { + return true; + } + return iotdbRpcDataSet_->next(); } shared_ptr SessionDataSet::next() { - if (!iotdbRpcDataSet_->hasCachedRecord() && !hasNext()) { - return nullptr; - } - iotdbRpcDataSet_->setHasCachedRecord(false); + if (!iotdbRpcDataSet_->hasCachedRecord() && !hasNext()) { + return nullptr; + } + iotdbRpcDataSet_->setHasCachedRecord(false); - return constructRowRecordFromValueArray(); + return constructRowRecordFromValueArray(); } int SessionDataSet::getFetchSize() { - return iotdbRpcDataSet_->getFetchSize(); + return iotdbRpcDataSet_->getFetchSize(); } void SessionDataSet::setFetchSize(int fetchSize) { - return iotdbRpcDataSet_->setFetchSize(fetchSize); + return iotdbRpcDataSet_->setFetchSize(fetchSize); } const std::vector& SessionDataSet::getColumnNames() const { - return iotdbRpcDataSet_->getColumnNameList(); + return iotdbRpcDataSet_->getColumnNameList(); } const std::vector& SessionDataSet::getColumnTypeList() const { - return iotdbRpcDataSet_->getColumnTypeList(); + return iotdbRpcDataSet_->getColumnTypeList(); } void SessionDataSet::closeOperationHandle(bool forceClose) { - iotdbRpcDataSet_->close(forceClose); + iotdbRpcDataSet_->close(forceClose); } bool SessionDataSet::DataIterator::next() { - return iotdbRpcDataSet_->next(); + return iotdbRpcDataSet_->next(); } bool SessionDataSet::DataIterator::isNull(const std::string& columnName) { - return iotdbRpcDataSet_->isNullByColumnName(columnName); + return iotdbRpcDataSet_->isNullByColumnName(columnName); } bool SessionDataSet::DataIterator::isNullByIndex(int32_t columnIndex) { - return iotdbRpcDataSet_->isNullByIndex(columnIndex); + return iotdbRpcDataSet_->isNullByIndex(columnIndex); } boost::optional SessionDataSet::DataIterator::getBooleanByIndex(int32_t columnIndex) { - return iotdbRpcDataSet_->getBooleanByIndex(columnIndex); + return iotdbRpcDataSet_->getBooleanByIndex(columnIndex); } boost::optional SessionDataSet::DataIterator::getBoolean(const std::string& columnName) { - return iotdbRpcDataSet_->getBoolean(columnName); + return iotdbRpcDataSet_->getBoolean(columnName); } boost::optional SessionDataSet::DataIterator::getDoubleByIndex(int32_t columnIndex) { - return iotdbRpcDataSet_->getDoubleByIndex(columnIndex); + return iotdbRpcDataSet_->getDoubleByIndex(columnIndex); } boost::optional SessionDataSet::DataIterator::getDouble(const std::string& columnName) { - return iotdbRpcDataSet_->getDouble(columnName); + return iotdbRpcDataSet_->getDouble(columnName); } boost::optional SessionDataSet::DataIterator::getFloatByIndex(int32_t columnIndex) { - return iotdbRpcDataSet_->getFloatByIndex(columnIndex); + return iotdbRpcDataSet_->getFloatByIndex(columnIndex); } boost::optional SessionDataSet::DataIterator::getFloat(const std::string& columnName) { - return iotdbRpcDataSet_->getFloat(columnName); + return iotdbRpcDataSet_->getFloat(columnName); } boost::optional SessionDataSet::DataIterator::getIntByIndex(int32_t columnIndex) { - return iotdbRpcDataSet_->getIntByIndex(columnIndex); + return iotdbRpcDataSet_->getIntByIndex(columnIndex); } boost::optional SessionDataSet::DataIterator::getInt(const std::string& columnName) { - return iotdbRpcDataSet_->getInt(columnName); + return iotdbRpcDataSet_->getInt(columnName); } boost::optional SessionDataSet::DataIterator::getLongByIndex(int32_t columnIndex) { - return iotdbRpcDataSet_->getLongByIndex(columnIndex); + return iotdbRpcDataSet_->getLongByIndex(columnIndex); } boost::optional SessionDataSet::DataIterator::getLong(const std::string& columnName) { - return iotdbRpcDataSet_->getLong(columnName); + return iotdbRpcDataSet_->getLong(columnName); } boost::optional SessionDataSet::DataIterator::getStringByIndex(int32_t columnIndex) { - return iotdbRpcDataSet_->getStringByIndex(columnIndex); + return iotdbRpcDataSet_->getStringByIndex(columnIndex); } -boost::optional SessionDataSet::DataIterator::getString(const std::string& columnName) { - return iotdbRpcDataSet_->getString(columnName); +boost::optional +SessionDataSet::DataIterator::getString(const std::string& columnName) { + return iotdbRpcDataSet_->getString(columnName); } boost::optional SessionDataSet::DataIterator::getTimestampByIndex(int32_t columnIndex) { - return iotdbRpcDataSet_->getTimestampByIndex(columnIndex); + return iotdbRpcDataSet_->getTimestampByIndex(columnIndex); } boost::optional SessionDataSet::DataIterator::getTimestamp(const std::string& columnName) { - return iotdbRpcDataSet_->getTimestamp(columnName); + return iotdbRpcDataSet_->getTimestamp(columnName); } -boost::optional SessionDataSet::DataIterator::getDateByIndex(int32_t columnIndex) { - return iotdbRpcDataSet_->getDateByIndex(columnIndex); +boost::optional +SessionDataSet::DataIterator::getDateByIndex(int32_t columnIndex) { + return iotdbRpcDataSet_->getDateByIndex(columnIndex); } -boost::optional SessionDataSet::DataIterator::getDate(const std::string& columnName) { - return iotdbRpcDataSet_->getDate(columnName); +boost::optional +SessionDataSet::DataIterator::getDate(const std::string& columnName) { + return iotdbRpcDataSet_->getDate(columnName); } int32_t SessionDataSet::DataIterator::findColumn(const std::string& columnName) { - return iotdbRpcDataSet_->findColumn(columnName); + return iotdbRpcDataSet_->findColumn(columnName); } const std::vector& SessionDataSet::DataIterator::getColumnNames() const { - return iotdbRpcDataSet_->getColumnNameList(); + return iotdbRpcDataSet_->getColumnNameList(); } const std::vector& SessionDataSet::DataIterator::getColumnTypeList() const { - return iotdbRpcDataSet_->getColumnTypeList(); + return iotdbRpcDataSet_->getColumnTypeList(); } shared_ptr SessionDataSet::constructRowRecordFromValueArray() { - std::vector outFields; - for (int i = iotdbRpcDataSet_->getValueColumnStartIndex(); i < iotdbRpcDataSet_->getColumnSize(); i++) { - Field field; - std::string columnName = iotdbRpcDataSet_->getColumnNameList().at(i); - if (!iotdbRpcDataSet_->isNullByColumnName(columnName)) { - TSDataType::TSDataType dataType = iotdbRpcDataSet_->getDataType(columnName); - field.dataType = dataType; - switch (dataType) { - case TSDataType::BOOLEAN: - field.boolV = iotdbRpcDataSet_->getBoolean(columnName); - break; - case TSDataType::INT32: - field.intV = iotdbRpcDataSet_->getInt(columnName); - break; - case TSDataType::DATE: - field.dateV = iotdbRpcDataSet_->getDate(columnName); - break; - case TSDataType::INT64: - case TSDataType::TIMESTAMP: - field.longV = iotdbRpcDataSet_->getLong(columnName); - break; - case TSDataType::FLOAT: - field.floatV = iotdbRpcDataSet_->getFloat(columnName); - break; - case TSDataType::DOUBLE: - field.doubleV = iotdbRpcDataSet_->getDouble(columnName); - break; - case TSDataType::TEXT: - case TSDataType::BLOB: - case TSDataType::STRING: - case TSDataType::OBJECT: - field.stringV = iotdbRpcDataSet_->getBinary(columnName)->getStringValue(); - break; - default: - throw UnSupportedDataTypeException("Data type %s is not supported." + dataType); - } - } - outFields.emplace_back(field); + std::vector outFields; + for (int i = iotdbRpcDataSet_->getValueColumnStartIndex(); i < iotdbRpcDataSet_->getColumnSize(); + i++) { + Field field; + std::string columnName = iotdbRpcDataSet_->getColumnNameList().at(i); + if (!iotdbRpcDataSet_->isNullByColumnName(columnName)) { + TSDataType::TSDataType dataType = iotdbRpcDataSet_->getDataType(columnName); + field.dataType = dataType; + switch (dataType) { + case TSDataType::BOOLEAN: + field.boolV = iotdbRpcDataSet_->getBoolean(columnName); + break; + case TSDataType::INT32: + field.intV = iotdbRpcDataSet_->getInt(columnName); + break; + case TSDataType::DATE: + field.dateV = iotdbRpcDataSet_->getDate(columnName); + break; + case TSDataType::INT64: + case TSDataType::TIMESTAMP: + field.longV = iotdbRpcDataSet_->getLong(columnName); + break; + case TSDataType::FLOAT: + field.floatV = iotdbRpcDataSet_->getFloat(columnName); + break; + case TSDataType::DOUBLE: + field.doubleV = iotdbRpcDataSet_->getDouble(columnName); + break; + case TSDataType::TEXT: + case TSDataType::BLOB: + case TSDataType::STRING: + case TSDataType::OBJECT: + field.stringV = iotdbRpcDataSet_->getBinary(columnName)->getStringValue(); + break; + default: + throw UnSupportedDataTypeException("Data type %s is not supported." + dataType); + } } - return std::make_shared(iotdbRpcDataSet_->getCurrentRowTime(), outFields); + outFields.emplace_back(field); + } + return std::make_shared(iotdbRpcDataSet_->getCurrentRowTime(), outFields); } diff --git a/iotdb-client/client-cpp/src/main/SessionDataSet.h b/iotdb-client/client-cpp/src/main/SessionDataSet.h index c796c5758e757..0f2c018d25661 100644 --- a/iotdb-client/client-cpp/src/main/SessionDataSet.h +++ b/iotdb-client/client-cpp/src/main/SessionDataSet.h @@ -30,117 +30,95 @@ class RowRecord { public: - int64_t timestamp; - std::vector fields; + int64_t timestamp; + std::vector fields; - explicit RowRecord(int64_t timestamp); - RowRecord(int64_t timestamp, const std::vector& fields); - explicit RowRecord(const std::vector& fields); - RowRecord(); + explicit RowRecord(int64_t timestamp); + RowRecord(int64_t timestamp, const std::vector& fields); + explicit RowRecord(const std::vector& fields); + RowRecord(); - void addField(const Field& f); - std::string toString(); + void addField(const Field& f); + std::string toString(); }; class SessionDataSet { public: - SessionDataSet(const std::string& sql, - const std::vector& columnNameList, - const std::vector& columnTypeList, - const std::map& columnNameIndex, - int64_t queryId, - int64_t statementId, - std::shared_ptr client, - int64_t sessionId, - const std::vector& queryResult, - bool ignoreTimestamp, - int64_t timeout, - bool moreData, - int32_t fetchSize, - const std::string& zoneId, - int32_t timeFactor, - std::vector& columnIndex2TsBlockColumnIndexList) { - iotdbRpcDataSet_ = std::make_shared(sql, - columnNameList, - columnTypeList, - columnNameIndex, - ignoreTimestamp, - moreData, - queryId, - statementId, - client, - sessionId, - queryResult, - fetchSize, - timeout, - zoneId, - IoTDBRpcDataSet::DEFAULT_TIME_FORMAT, - timeFactor, - columnIndex2TsBlockColumnIndexList); - } - - ~SessionDataSet() = default; - - bool hasNext(); - shared_ptr next(); - - int getFetchSize(); - void setFetchSize(int fetchSize); - - const std::vector& getColumnNames() const; - const std::vector& getColumnTypeList() const; - void closeOperationHandle(bool forceClose = false); - - class DataIterator { - std::shared_ptr iotdbRpcDataSet_; + SessionDataSet(const std::string& sql, const std::vector& columnNameList, + const std::vector& columnTypeList, + const std::map& columnNameIndex, int64_t queryId, + int64_t statementId, std::shared_ptr client, + int64_t sessionId, const std::vector& queryResult, + bool ignoreTimestamp, int64_t timeout, bool moreData, int32_t fetchSize, + const std::string& zoneId, int32_t timeFactor, + std::vector& columnIndex2TsBlockColumnIndexList) { + iotdbRpcDataSet_ = std::make_shared( + sql, columnNameList, columnTypeList, columnNameIndex, ignoreTimestamp, moreData, queryId, + statementId, client, sessionId, queryResult, fetchSize, timeout, zoneId, + IoTDBRpcDataSet::DEFAULT_TIME_FORMAT, timeFactor, columnIndex2TsBlockColumnIndexList); + } + + ~SessionDataSet() = default; + + bool hasNext(); + shared_ptr next(); + + int getFetchSize(); + void setFetchSize(int fetchSize); + + const std::vector& getColumnNames() const; + const std::vector& getColumnTypeList() const; + void closeOperationHandle(bool forceClose = false); + + class DataIterator { + std::shared_ptr iotdbRpcDataSet_; - public: - DataIterator(std::shared_ptr iotdbRpcDataSet) : - iotdbRpcDataSet_(iotdbRpcDataSet) { - } + public: + DataIterator(std::shared_ptr iotdbRpcDataSet) + : iotdbRpcDataSet_(iotdbRpcDataSet) {} - bool next(); + bool next(); - bool isNull(const std::string& columnName); - bool isNullByIndex(int32_t columnIndex); + bool isNull(const std::string& columnName); + bool isNullByIndex(int32_t columnIndex); - boost::optional getBooleanByIndex(int32_t columnIndex); - boost::optional getBoolean(const std::string& columnName); + boost::optional getBooleanByIndex(int32_t columnIndex); + boost::optional getBoolean(const std::string& columnName); - boost::optional getDoubleByIndex(int32_t columnIndex); - boost::optional getDouble(const std::string& columnName); + boost::optional getDoubleByIndex(int32_t columnIndex); + boost::optional getDouble(const std::string& columnName); - boost::optional getFloatByIndex(int32_t columnIndex); - boost::optional getFloat(const std::string& columnName); + boost::optional getFloatByIndex(int32_t columnIndex); + boost::optional getFloat(const std::string& columnName); - boost::optional getIntByIndex(int32_t columnIndex); - boost::optional getInt(const std::string& columnName); + boost::optional getIntByIndex(int32_t columnIndex); + boost::optional getInt(const std::string& columnName); - boost::optional getLongByIndex(int32_t columnIndex); - boost::optional getLong(const std::string& columnName); + boost::optional getLongByIndex(int32_t columnIndex); + boost::optional getLong(const std::string& columnName); - boost::optional getStringByIndex(int32_t columnIndex); - boost::optional getString(const std::string& columnName); + boost::optional getStringByIndex(int32_t columnIndex); + boost::optional getString(const std::string& columnName); - boost::optional getTimestampByIndex(int32_t columnIndex); - boost::optional getTimestamp(const std::string& columnName); + boost::optional getTimestampByIndex(int32_t columnIndex); + boost::optional getTimestamp(const std::string& columnName); - boost::optional getDateByIndex(int32_t columnIndex); - boost::optional getDate(const std::string& columnName); + boost::optional getDateByIndex(int32_t columnIndex); + boost::optional getDate(const std::string& columnName); - int32_t findColumn(const std::string& columnName); - const std::vector& getColumnNames() const; - const std::vector& getColumnTypeList() const; - }; + int32_t findColumn(const std::string& columnName); + const std::vector& getColumnNames() const; + const std::vector& getColumnTypeList() const; + }; - DataIterator getIterator() { - return {iotdbRpcDataSet_}; - }; + DataIterator getIterator() { + return {iotdbRpcDataSet_}; + }; private: - std::shared_ptr constructRowRecordFromValueArray(); + std::shared_ptr constructRowRecordFromValueArray(); - std::shared_ptr iotdbRpcDataSet_; + std::shared_ptr iotdbRpcDataSet_; }; #endif diff --git a/iotdb-client/client-cpp/src/main/TableSession.cpp b/iotdb-client/client-cpp/src/main/TableSession.cpp index 35613cff6dab9..9cd80b7dd7897 100644 --- a/iotdb-client/client-cpp/src/main/TableSession.cpp +++ b/iotdb-client/client-cpp/src/main/TableSession.cpp @@ -22,24 +22,25 @@ #include "TableSession.h" #include "SessionDataSet.h" -void TableSession::insert(Tablet &tablet, bool sorted) { - session_->insertRelationalTablet(tablet, sorted); +void TableSession::insert(Tablet& tablet, bool sorted) { + session_->insertRelationalTablet(tablet, sorted); } -void TableSession::executeNonQueryStatement(const string &sql) { - session_->executeNonQueryStatement(sql); +void TableSession::executeNonQueryStatement(const string& sql) { + session_->executeNonQueryStatement(sql); } -unique_ptr TableSession::executeQueryStatement(const string &sql) { - return session_->executeQueryStatement(sql); +unique_ptr TableSession::executeQueryStatement(const string& sql) { + return session_->executeQueryStatement(sql); } -unique_ptr TableSession::executeQueryStatement(const string &sql, int64_t timeoutInMs) { - return session_->executeQueryStatement(sql, timeoutInMs); +unique_ptr TableSession::executeQueryStatement(const string& sql, + int64_t timeoutInMs) { + return session_->executeQueryStatement(sql, timeoutInMs); } string TableSession::getDatabase() { - return session_->getDatabase(); + return session_->getDatabase(); } void TableSession::open(bool enableRPCCompression) { - session_->open(enableRPCCompression); + session_->open(enableRPCCompression); } void TableSession::close() { - session_->close(); + session_->close(); } \ No newline at end of file diff --git a/iotdb-client/client-cpp/src/main/TableSession.h b/iotdb-client/client-cpp/src/main/TableSession.h index 09768439e83ea..d1eecfeeabaea 100644 --- a/iotdb-client/client-cpp/src/main/TableSession.h +++ b/iotdb-client/client-cpp/src/main/TableSession.h @@ -26,20 +26,21 @@ class TableSession { private: - std::shared_ptr session_; - string getDatabase(); + std::shared_ptr session_; + string getDatabase(); + public: - TableSession(std::shared_ptr session) { - this->session_ = session; - } - ~TableSession() {} + TableSession(std::shared_ptr session) { + this->session_ = session; + } + ~TableSession() {} - 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); - void open(bool enableRPCCompression = false); - void close(); + 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); + void open(bool enableRPCCompression = false); + void close(); }; #endif // IOTDB_TABLESESSION_H \ No newline at end of file diff --git a/iotdb-client/client-cpp/src/main/TableSessionBuilder.h b/iotdb-client/client-cpp/src/main/TableSessionBuilder.h index 9f76b84815ba6..3c9739ecc8edb 100644 --- a/iotdb-client/client-cpp/src/main/TableSessionBuilder.h +++ b/iotdb-client/client-cpp/src/main/TableSessionBuilder.h @@ -26,7 +26,7 @@ #include "AbstractSessionBuilder.h" class TableSessionBuilder : public AbstractSessionBuilder { - /* + /* std::string host; int rpcPort; std::string username; @@ -37,59 +37,60 @@ class TableSessionBuilder : public AbstractSessionBuilder { std::string database; */ public: - TableSessionBuilder* host(const std::string &host) { - AbstractSessionBuilder::host = host; - return this; - } - TableSessionBuilder* rpcPort(int rpcPort) { - AbstractSessionBuilder::rpcPort = rpcPort; - return this; - } - TableSessionBuilder* useSSL(bool useSSL) { - AbstractSessionBuilder::useSSL = useSSL; - return this; - } + TableSessionBuilder* host(const std::string& host) { + AbstractSessionBuilder::host = host; + return this; + } + TableSessionBuilder* rpcPort(int rpcPort) { + AbstractSessionBuilder::rpcPort = rpcPort; + return this; + } + TableSessionBuilder* useSSL(bool useSSL) { + AbstractSessionBuilder::useSSL = useSSL; + return this; + } - TableSessionBuilder* trustCertFilePath(const std::string &trustCertFilePath) { - AbstractSessionBuilder::trustCertFilePath = trustCertFilePath; - return this; - } + TableSessionBuilder* trustCertFilePath(const std::string& trustCertFilePath) { + AbstractSessionBuilder::trustCertFilePath = trustCertFilePath; + return this; + } - TableSessionBuilder* username(const std::string &username) { - AbstractSessionBuilder::username = username; - return this; - } - TableSessionBuilder* password(const std::string &password) { - AbstractSessionBuilder::password = password; - return this; - } - TableSessionBuilder* zoneId(const std::string &zoneId) { - AbstractSessionBuilder::zoneId = zoneId; - return this; - } - TableSessionBuilder* fetchSize(int fetchSize) { - AbstractSessionBuilder::fetchSize = fetchSize; - return this; - } - TableSessionBuilder* database(const std::string &database) { - AbstractSessionBuilder::database = database; - return this; - } - TableSessionBuilder* nodeUrls(const std::vector& nodeUrls) { - AbstractSessionBuilder::nodeUrls = nodeUrls; - return this; - } - std::shared_ptr build() { - if (!AbstractSessionBuilder::nodeUrls.empty() && - (AbstractSessionBuilder::host != DEFAULT_HOST || - AbstractSessionBuilder::rpcPort != DEFAULT_RPC_PORT)) { - throw IoTDBException("Session builder does not support setting node urls and host/rpcPort at the same time."); - } - sqlDialect = "table"; - auto newSession = std::make_shared(this); - newSession->open(false); - return std::make_shared(newSession); + TableSessionBuilder* username(const std::string& username) { + AbstractSessionBuilder::username = username; + return this; + } + TableSessionBuilder* password(const std::string& password) { + AbstractSessionBuilder::password = password; + return this; + } + TableSessionBuilder* zoneId(const std::string& zoneId) { + AbstractSessionBuilder::zoneId = zoneId; + return this; + } + TableSessionBuilder* fetchSize(int fetchSize) { + AbstractSessionBuilder::fetchSize = fetchSize; + return this; + } + TableSessionBuilder* database(const std::string& database) { + AbstractSessionBuilder::database = database; + return this; + } + TableSessionBuilder* nodeUrls(const std::vector& nodeUrls) { + AbstractSessionBuilder::nodeUrls = nodeUrls; + return this; + } + std::shared_ptr build() { + if (!AbstractSessionBuilder::nodeUrls.empty() && + (AbstractSessionBuilder::host != DEFAULT_HOST || + AbstractSessionBuilder::rpcPort != DEFAULT_RPC_PORT)) { + throw IoTDBException( + "Session builder does not support setting node urls and host/rpcPort at the same time."); } + sqlDialect = "table"; + auto newSession = std::make_shared(this); + newSession->open(false); + return std::make_shared(newSession); + } }; #endif // IOTDB_TABLESESSIONBUILDER_H \ No newline at end of file diff --git a/iotdb-client/client-cpp/src/main/ThriftConnection.cpp b/iotdb-client/client-cpp/src/main/ThriftConnection.cpp index 3a7989a5e7654..b02cb03c45402 100644 --- a/iotdb-client/client-cpp/src/main/ThriftConnection.cpp +++ b/iotdb-client/client-cpp/src/main/ThriftConnection.cpp @@ -29,159 +29,143 @@ const int ThriftConnection::THRIFT_MAX_FRAME_SIZE = 1048576; const int ThriftConnection::CONNECTION_TIMEOUT_IN_MS = 1000; const int ThriftConnection::DEFAULT_FETCH_SIZE = 10000; -ThriftConnection::ThriftConnection(const TEndPoint& endPoint, - int thriftDefaultBufferSize, - int thriftMaxFrameSize, - int connectionTimeoutInMs, - int fetchSize) - : endPoint_(endPoint), - thriftDefaultBufferSize_(thriftDefaultBufferSize), - thriftMaxFrameSize_(thriftMaxFrameSize), - connectionTimeoutInMs_(connectionTimeoutInMs), - fetchSize_(fetchSize){ -} +ThriftConnection::ThriftConnection(const TEndPoint& endPoint, int thriftDefaultBufferSize, + int thriftMaxFrameSize, int connectionTimeoutInMs, int fetchSize) + : endPoint_(endPoint), thriftDefaultBufferSize_(thriftDefaultBufferSize), + thriftMaxFrameSize_(thriftMaxFrameSize), connectionTimeoutInMs_(connectionTimeoutInMs), + fetchSize_(fetchSize) {} ThriftConnection::~ThriftConnection() = default; void ThriftConnection::initZoneId() { - if (!zoneId_.empty()) { - return; - } + if (!zoneId_.empty()) { + return; + } - time_t ts = 0; - struct tm tmv{}; -#if defined(_WIN64) || defined (WIN32) || defined (_WIN32) - localtime_s(&tmv, &ts); + time_t ts = 0; + struct tm tmv {}; +#if defined(_WIN64) || defined(WIN32) || defined(_WIN32) + localtime_s(&tmv, &ts); #else - localtime_r(&ts, &tmv); + localtime_r(&ts, &tmv); #endif - char zoneStr[32]; - strftime(zoneStr, sizeof(zoneStr), "%z", &tmv); - zoneId_ = zoneStr; + char zoneStr[32]; + strftime(zoneStr, sizeof(zoneStr), "%z", &tmv); + zoneId_ = zoneStr; } -void ThriftConnection::init(const std::string& username, - const std::string& password, - bool enableRPCCompression, - bool useSSL, - const std::string& trustCertFilePath, - const std::string& zoneId, +void ThriftConnection::init(const std::string& username, const std::string& password, + bool enableRPCCompression, bool useSSL, + const std::string& trustCertFilePath, const std::string& zoneId, const std::string& version) { - if (useSSL) { + if (useSSL) { #if WITH_SSL - socketFactory_->loadTrustedCertificates(trustCertFilePath.c_str()); - socketFactory_->authenticate(false); - auto sslSocket = socketFactory_->createSocket(endPoint_.ip, endPoint_.port); - sslSocket->setConnTimeout(connectionTimeoutInMs_); - transport_ = std::make_shared(sslSocket); + socketFactory_->loadTrustedCertificates(trustCertFilePath.c_str()); + socketFactory_->authenticate(false); + auto sslSocket = socketFactory_->createSocket(endPoint_.ip, endPoint_.port); + sslSocket->setConnTimeout(connectionTimeoutInMs_); + transport_ = std::make_shared(sslSocket); #else - throw IoTDBException("SSL/TLS support is not enabled in this build. " - "Please rebuild with -DWITH_SSL=ON flag " - "or use non-SSL connection."); + throw IoTDBException("SSL/TLS support is not enabled in this build. " + "Please rebuild with -DWITH_SSL=ON flag " + "or use non-SSL connection."); #endif - } else { - auto socket = std::make_shared(endPoint_.ip, endPoint_.port); - socket->setConnTimeout(connectionTimeoutInMs_); - transport_ = std::make_shared(socket); - } - if (!transport_->isOpen()) { - try { - transport_->open(); - } - catch (TTransportException& e) { - throw IoTDBConnectionException(e.what()); - } - } - if (zoneId.empty()) { - initZoneId(); - } - else { - this->zoneId_ = zoneId; + } else { + auto socket = std::make_shared(endPoint_.ip, endPoint_.port); + socket->setConnTimeout(connectionTimeoutInMs_); + transport_ = std::make_shared(socket); + } + if (!transport_->isOpen()) { + try { + transport_->open(); + } catch (TTransportException& e) { + throw IoTDBConnectionException(e.what()); } + } + if (zoneId.empty()) { + initZoneId(); + } else { + this->zoneId_ = zoneId; + } - if (enableRPCCompression) { - std::shared_ptr protocol(new TCompactProtocol(transport_)); - client_ = std::make_shared(protocol); - } - else { - std::shared_ptr protocol(new TBinaryProtocol(transport_)); - client_ = std::make_shared(protocol); - } + if (enableRPCCompression) { + std::shared_ptr protocol(new TCompactProtocol(transport_)); + client_ = std::make_shared(protocol); + } else { + std::shared_ptr protocol(new TBinaryProtocol(transport_)); + client_ = std::make_shared(protocol); + } - std::map configuration; - configuration["version"] = version; - TSOpenSessionReq openReq; - openReq.__set_username(username); - openReq.__set_password(password); - openReq.__set_zoneId(this->zoneId_); - openReq.__set_configuration(configuration); - try { - TSOpenSessionResp openResp; - client_->openSession(openResp, openReq); - RpcUtils::verifySuccess(openResp.status); - sessionId_ = openResp.sessionId; - statementId_ = client_->requestStatementId(sessionId_); - } - catch (const TTransportException& e) { - transport_->close(); - throw IoTDBConnectionException(e.what()); - } catch (const IoTDBException& e) { - transport_->close(); - throw IoTDBException(e.what()); - } catch (const std::exception& e) { - transport_->close(); - throw IoTDBException(e.what()); - } + std::map configuration; + configuration["version"] = version; + TSOpenSessionReq openReq; + openReq.__set_username(username); + openReq.__set_password(password); + openReq.__set_zoneId(this->zoneId_); + openReq.__set_configuration(configuration); + try { + TSOpenSessionResp openResp; + client_->openSession(openResp, openReq); + RpcUtils::verifySuccess(openResp.status); + sessionId_ = openResp.sessionId; + statementId_ = client_->requestStatementId(sessionId_); + } catch (const TTransportException& e) { + transport_->close(); + throw IoTDBConnectionException(e.what()); + } catch (const IoTDBException& e) { + transport_->close(); + throw IoTDBException(e.what()); + } catch (const std::exception& e) { + transport_->close(); + throw IoTDBException(e.what()); + } } -std::unique_ptr ThriftConnection::executeQueryStatement(const std::string& sql, int64_t timeoutInMs) { - TSExecuteStatementReq req; - req.__set_sessionId(sessionId_); - req.__set_statementId(statementId_); - req.__set_statement(sql); - req.__set_timeout(timeoutInMs); - TSExecuteStatementResp resp; - try { - client_->executeQueryStatementV2(resp, req); - RpcUtils::verifySuccess(resp.status); - } - catch (const TTransportException& e) { - throw IoTDBConnectionException(e.what()); - } catch (const IoTDBException& e) { - throw IoTDBConnectionException(e.what()); - } catch (const std::exception& e) { - throw IoTDBException(e.what()); - } - std::shared_ptr queryDataSet(new TSQueryDataSet(resp.queryDataSet)); - return std::unique_ptr(new SessionDataSet("", resp.columns, resp.dataTypeList, - resp.columnNameIndexMap, resp.queryId, statementId_, - client_, sessionId_, resp.queryResult, resp.ignoreTimeStamp, - connectionTimeoutInMs_, resp.moreData, fetchSize_, zoneId_, - timeFactor_, resp.columnIndex2TsBlockColumnIndexList)); +std::unique_ptr ThriftConnection::executeQueryStatement(const std::string& sql, + int64_t timeoutInMs) { + TSExecuteStatementReq req; + req.__set_sessionId(sessionId_); + req.__set_statementId(statementId_); + req.__set_statement(sql); + req.__set_timeout(timeoutInMs); + TSExecuteStatementResp resp; + try { + client_->executeQueryStatementV2(resp, req); + RpcUtils::verifySuccess(resp.status); + } catch (const TTransportException& e) { + throw IoTDBConnectionException(e.what()); + } catch (const IoTDBException& e) { + throw IoTDBConnectionException(e.what()); + } catch (const std::exception& e) { + throw IoTDBException(e.what()); + } + std::shared_ptr queryDataSet(new TSQueryDataSet(resp.queryDataSet)); + return std::unique_ptr(new SessionDataSet( + "", resp.columns, resp.dataTypeList, resp.columnNameIndexMap, resp.queryId, statementId_, + client_, sessionId_, resp.queryResult, resp.ignoreTimeStamp, connectionTimeoutInMs_, + resp.moreData, fetchSize_, zoneId_, timeFactor_, resp.columnIndex2TsBlockColumnIndexList)); } void ThriftConnection::close() { - try { - if (client_) { - TSCloseSessionReq req; - req.__set_sessionId(sessionId_); - TSStatus tsStatus; - client_->closeSession(tsStatus, req); - } - } - catch (const TTransportException& e) { - throw IoTDBConnectionException(e.what()); - } catch (const std::exception& e) { - throw IoTDBConnectionException(e.what()); + try { + if (client_) { + TSCloseSessionReq req; + req.__set_sessionId(sessionId_); + TSStatus tsStatus; + client_->closeSession(tsStatus, req); } + } catch (const TTransportException& e) { + throw IoTDBConnectionException(e.what()); + } catch (const std::exception& e) { + throw IoTDBConnectionException(e.what()); + } - try { - if (transport_->isOpen()) { - transport_->close(); - } - } - catch (const std::exception& e) { - throw IoTDBConnectionException(e.what()); + try { + if (transport_->isOpen()) { + transport_->close(); } + } catch (const std::exception& e) { + throw IoTDBConnectionException(e.what()); + } } diff --git a/iotdb-client/client-cpp/src/main/ThriftConnection.h b/iotdb-client/client-cpp/src/main/ThriftConnection.h index 6dae68357fdbc..ab094c6608c52 100644 --- a/iotdb-client/client-cpp/src/main/ThriftConnection.h +++ b/iotdb-client/client-cpp/src/main/ThriftConnection.h @@ -29,51 +29,49 @@ class SessionDataSet; class ThriftConnection { public: - static const int THRIFT_DEFAULT_BUFFER_SIZE; - static const int THRIFT_MAX_FRAME_SIZE; - static const int CONNECTION_TIMEOUT_IN_MS; - static const int DEFAULT_FETCH_SIZE; + static const int THRIFT_DEFAULT_BUFFER_SIZE; + static const int THRIFT_MAX_FRAME_SIZE; + static const int CONNECTION_TIMEOUT_IN_MS; + static const int DEFAULT_FETCH_SIZE; - explicit ThriftConnection(const TEndPoint& endPoint, - int thriftDefaultBufferSize = THRIFT_DEFAULT_BUFFER_SIZE, - int thriftMaxFrameSize = THRIFT_MAX_FRAME_SIZE, - int connectionTimeoutInMs = CONNECTION_TIMEOUT_IN_MS, - int fetchSize = DEFAULT_FETCH_SIZE); + explicit ThriftConnection(const TEndPoint& endPoint, + int thriftDefaultBufferSize = THRIFT_DEFAULT_BUFFER_SIZE, + int thriftMaxFrameSize = THRIFT_MAX_FRAME_SIZE, + int connectionTimeoutInMs = CONNECTION_TIMEOUT_IN_MS, + int fetchSize = DEFAULT_FETCH_SIZE); - ~ThriftConnection(); + ~ThriftConnection(); - void init(const std::string& username, - const std::string& password, - bool enableRPCCompression = false, - bool useSSL = false, - const std::string& trustCertFilePath = "", - const std::string& zoneId = std::string(), - const std::string& version = "V_1_0"); + void init(const std::string& username, const std::string& password, + bool enableRPCCompression = false, bool useSSL = false, + const std::string& trustCertFilePath = "", const std::string& zoneId = std::string(), + const std::string& version = "V_1_0"); - std::unique_ptr executeQueryStatement(const std::string& sql, int64_t timeoutInMs = -1); + std::unique_ptr executeQueryStatement(const std::string& sql, + int64_t timeoutInMs = -1); - void close(); + void close(); private: - TEndPoint endPoint_; + TEndPoint endPoint_; - int thriftDefaultBufferSize_; - int thriftMaxFrameSize_; - int connectionTimeoutInMs_; - int fetchSize_; + int thriftDefaultBufferSize_; + int thriftMaxFrameSize_; + int connectionTimeoutInMs_; + int fetchSize_; #if WITH_SSL - std::shared_ptr socketFactory_ = - std::make_shared(); + std::shared_ptr socketFactory_ = + std::make_shared(); #endif - std::shared_ptr transport_; - std::shared_ptr client_; - int64_t sessionId_{}; - int64_t statementId_{}; - std::string zoneId_; - int timeFactor_{}; + std::shared_ptr transport_; + std::shared_ptr client_; + int64_t sessionId_{}; + int64_t statementId_{}; + std::string zoneId_; + int timeFactor_{}; - void initZoneId(); + void initZoneId(); }; #endif diff --git a/iotdb-client/client-cpp/src/main/TsBlock.cpp b/iotdb-client/client-cpp/src/main/TsBlock.cpp index 92afbef3f270f..e1c5840900cbe 100644 --- a/iotdb-client/client-cpp/src/main/TsBlock.cpp +++ b/iotdb-client/client-cpp/src/main/TsBlock.cpp @@ -21,101 +21,98 @@ #include #include "TsBlock.h" -std::shared_ptr TsBlock::create(int32_t positionCount, - std::shared_ptr timeColumn, +std::shared_ptr TsBlock::create(int32_t positionCount, std::shared_ptr timeColumn, std::vector> valueColumns) { - if (valueColumns.empty()) { - throw std::invalid_argument("valueColumns cannot be empty"); - } - return std::shared_ptr(new TsBlock(positionCount, std::move(timeColumn), std::move(valueColumns))); + if (valueColumns.empty()) { + throw std::invalid_argument("valueColumns cannot be empty"); + } + return std::shared_ptr( + new TsBlock(positionCount, std::move(timeColumn), std::move(valueColumns))); } std::shared_ptr TsBlock::deserialize(const std::string& data) { - MyStringBuffer buffer(data); - - // Read value column count - int32_t valueColumnCount = buffer.getInt(); - if (valueColumnCount < 0) { - throw IoTDBException("TsBlock::deserialize: negative valueColumnCount"); - } - const int64_t minHeaderBytes = - 9LL + 2LL * static_cast(valueColumnCount); - if (minHeaderBytes > static_cast(data.size())) { - throw IoTDBException("TsBlock::deserialize: truncated header"); - } - - // Read value column data types - std::vector valueColumnDataTypes(valueColumnCount); - for (int32_t i = 0; i < valueColumnCount; i++) { - valueColumnDataTypes[i] = static_cast(buffer.getChar()); - } - - // Read position count - int32_t positionCount = buffer.getInt(); - if (positionCount < 0) { - throw IoTDBException("TsBlock::deserialize: negative positionCount"); - } - - // Read column encodings - std::vector columnEncodings(valueColumnCount + 1); - for (int32_t i = 0; i < valueColumnCount + 1; i++) { - columnEncodings[i] = static_cast(buffer.getChar()); - } - - // Read time column - auto timeColumnDecoder = getColumnDecoder(columnEncodings[0]); - auto timeColumn = timeColumnDecoder->readColumn(buffer, TSDataType::INT64, positionCount); - - // Read value columns - std::vector> valueColumns(valueColumnCount); - for (int32_t i = 0; i < valueColumnCount; i++) { - auto valueColumnDecoder = getColumnDecoder(columnEncodings[i + 1]); - valueColumns[i] = valueColumnDecoder->readColumn(buffer, valueColumnDataTypes[i], positionCount); - } - - return create(positionCount, std::move(timeColumn), std::move(valueColumns)); + MyStringBuffer buffer(data); + + // Read value column count + int32_t valueColumnCount = buffer.getInt(); + if (valueColumnCount < 0) { + throw IoTDBException("TsBlock::deserialize: negative valueColumnCount"); + } + const int64_t minHeaderBytes = 9LL + 2LL * static_cast(valueColumnCount); + if (minHeaderBytes > static_cast(data.size())) { + throw IoTDBException("TsBlock::deserialize: truncated header"); + } + + // Read value column data types + std::vector valueColumnDataTypes(valueColumnCount); + for (int32_t i = 0; i < valueColumnCount; i++) { + valueColumnDataTypes[i] = static_cast(buffer.getChar()); + } + + // Read position count + int32_t positionCount = buffer.getInt(); + if (positionCount < 0) { + throw IoTDBException("TsBlock::deserialize: negative positionCount"); + } + + // Read column encodings + std::vector columnEncodings(valueColumnCount + 1); + for (int32_t i = 0; i < valueColumnCount + 1; i++) { + columnEncodings[i] = static_cast(buffer.getChar()); + } + + // Read time column + auto timeColumnDecoder = getColumnDecoder(columnEncodings[0]); + auto timeColumn = timeColumnDecoder->readColumn(buffer, TSDataType::INT64, positionCount); + + // Read value columns + std::vector> valueColumns(valueColumnCount); + for (int32_t i = 0; i < valueColumnCount; i++) { + auto valueColumnDecoder = getColumnDecoder(columnEncodings[i + 1]); + valueColumns[i] = + valueColumnDecoder->readColumn(buffer, valueColumnDataTypes[i], positionCount); + } + + return create(positionCount, std::move(timeColumn), std::move(valueColumns)); } -TsBlock::TsBlock(int32_t positionCount, - std::shared_ptr timeColumn, +TsBlock::TsBlock(int32_t positionCount, std::shared_ptr timeColumn, std::vector> valueColumns) - : positionCount_(positionCount), - timeColumn_(std::move(timeColumn)), - valueColumns_(std::move(valueColumns)) { -} + : positionCount_(positionCount), timeColumn_(std::move(timeColumn)), + valueColumns_(std::move(valueColumns)) {} int32_t TsBlock::getPositionCount() const { - return positionCount_; + return positionCount_; } int64_t TsBlock::getStartTime() const { - return timeColumn_->getLong(0); + return timeColumn_->getLong(0); } int64_t TsBlock::getEndTime() const { - return timeColumn_->getLong(positionCount_ - 1); + return timeColumn_->getLong(positionCount_ - 1); } bool TsBlock::isEmpty() const { - return positionCount_ == 0; + return positionCount_ == 0; } int64_t TsBlock::getTimeByIndex(int32_t index) const { - return timeColumn_->getLong(index); + return timeColumn_->getLong(index); } int32_t TsBlock::getValueColumnCount() const { - return static_cast(valueColumns_.size()); + return static_cast(valueColumns_.size()); } const std::shared_ptr TsBlock::getTimeColumn() const { - return timeColumn_; + return timeColumn_; } const std::vector>& TsBlock::getValueColumns() const { - return valueColumns_; + return valueColumns_; } const std::shared_ptr TsBlock::getColumn(int32_t columnIndex) const { - return valueColumns_[columnIndex]; + return valueColumns_[columnIndex]; } diff --git a/iotdb-client/client-cpp/src/main/TsBlock.h b/iotdb-client/client-cpp/src/main/TsBlock.h index 2ca6b0197445d..0ffa8c0af6c1b 100644 --- a/iotdb-client/client-cpp/src/main/TsBlock.h +++ b/iotdb-client/client-cpp/src/main/TsBlock.h @@ -26,30 +26,28 @@ class TsBlock { public: - static std::shared_ptr create(int32_t positionCount, - std::shared_ptr timeColumn, - std::vector> valueColumns); - - static std::shared_ptr deserialize(const std::string& data); - - int32_t getPositionCount() const; - int64_t getStartTime() const; - int64_t getEndTime() const; - bool isEmpty() const; - int64_t getTimeByIndex(int32_t index) const; - int32_t getValueColumnCount() const; - const std::shared_ptr getTimeColumn() const; - const std::vector>& getValueColumns() const; - const std::shared_ptr getColumn(int32_t columnIndex) const; + static std::shared_ptr create(int32_t positionCount, std::shared_ptr timeColumn, + std::vector> valueColumns); + + static std::shared_ptr deserialize(const std::string& data); + + int32_t getPositionCount() const; + int64_t getStartTime() const; + int64_t getEndTime() const; + bool isEmpty() const; + int64_t getTimeByIndex(int32_t index) const; + int32_t getValueColumnCount() const; + const std::shared_ptr getTimeColumn() const; + const std::vector>& getValueColumns() const; + const std::shared_ptr getColumn(int32_t columnIndex) const; private: - TsBlock(int32_t positionCount, - std::shared_ptr timeColumn, - std::vector> valueColumns); + TsBlock(int32_t positionCount, std::shared_ptr timeColumn, + std::vector> valueColumns); - std::shared_ptr timeColumn_; - std::vector> valueColumns_; - int32_t positionCount_; + std::shared_ptr timeColumn_; + std::vector> valueColumns_; + int32_t positionCount_; }; #endif diff --git a/iotdb-client/client-cpp/src/test/cpp/sessionCIT.cpp b/iotdb-client/client-cpp/src/test/cpp/sessionCIT.cpp index bfe823a84fba3..f56e10bb5ae16 100644 --- a/iotdb-client/client-cpp/src/test/cpp/sessionCIT.cpp +++ b/iotdb-client/client-cpp/src/test/cpp/sessionCIT.cpp @@ -31,60 +31,62 @@ static int global_test_id = 0; class CaseReporter { public: - CaseReporter(const char* caseNameArg) : caseName(caseNameArg) { - test_id = global_test_id++; - std::cout << "C-API Test " << test_id << ": " << caseName << std::endl; - } - ~CaseReporter() { - std::cout << "C-API Test " << test_id << ": " << caseName << " Done" << std::endl << std::endl; - } + CaseReporter(const char* caseNameArg) : caseName(caseNameArg) { + test_id = global_test_id++; + std::cout << "C-API Test " << test_id << ": " << caseName << std::endl; + } + ~CaseReporter() { + std::cout << "C-API Test " << test_id << ": " << caseName << " Done" << std::endl << std::endl; + } + private: - const char* caseName; - int test_id; + const char* caseName; + int test_id; }; static const char* testTimeseries[] = {"root.ctest.d1.s1", "root.ctest.d1.s2", "root.ctest.d1.s3"}; static const int testTimeseriesCount = 3; static void dropTimeseriesIfExists(CSession* session, const char* path) { - bool exists = false; - REQUIRE(ts_session_check_timeseries_exists(session, path, &exists) == TS_OK); - if (exists) { - REQUIRE(ts_session_delete_timeseries(session, path) == TS_OK); - } + bool exists = false; + REQUIRE(ts_session_check_timeseries_exists(session, path, &exists) == TS_OK); + if (exists) { + REQUIRE(ts_session_delete_timeseries(session, path) == TS_OK); + } } -static void ensureTimeseries(CSession* session, const char* path, TSDataType_C type, TSEncoding_C encoding, - TSCompressionType_C compression) { - dropTimeseriesIfExists(session, path); - REQUIRE(ts_session_create_timeseries(session, path, type, encoding, compression) == TS_OK); +static void ensureTimeseries(CSession* session, const char* path, TSDataType_C type, + TSEncoding_C encoding, TSCompressionType_C compression) { + dropTimeseriesIfExists(session, path); + REQUIRE(ts_session_create_timeseries(session, path, type, encoding, compression) == TS_OK); } static int queryRowCount(CSession* session, const char* sql, int fetchSize = 1024) { - CSessionDataSet* dataSet = nullptr; - REQUIRE(ts_session_execute_query(session, sql, &dataSet) == TS_OK); - REQUIRE(dataSet != nullptr); - ts_dataset_set_fetch_size(dataSet, fetchSize); - int count = 0; - while (ts_dataset_has_next(dataSet)) { - CRowRecord* record = ts_dataset_next(dataSet); - REQUIRE(record != nullptr); - ++count; - ts_row_record_destroy(record); - } - ts_dataset_destroy(dataSet); - return count; + CSessionDataSet* dataSet = nullptr; + REQUIRE(ts_session_execute_query(session, sql, &dataSet) == TS_OK); + REQUIRE(dataSet != nullptr); + ts_dataset_set_fetch_size(dataSet, fetchSize); + int count = 0; + while (ts_dataset_has_next(dataSet)) { + CRowRecord* record = ts_dataset_next(dataSet); + REQUIRE(record != nullptr); + ++count; + ts_row_record_destroy(record); + } + ts_dataset_destroy(dataSet); + return count; } static void dropDatabaseIfExists(CSession* session, const char* database) { - TsStatus status = ts_session_delete_database(session, database); - (void)status; + TsStatus status = ts_session_delete_database(session, database); + (void)status; } static void prepareTimeseries() { - for (int i = 0; i < testTimeseriesCount; i++) { - ensureTimeseries(g_session, testTimeseries[i], TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); - } + for (int i = 0; i < testTimeseriesCount; i++) { + ensureTimeseries(g_session, testTimeseries[i], TS_TYPE_INT64, TS_ENCODING_RLE, + TS_COMPRESSION_SNAPPY); + } } /* ============================================================ @@ -92,34 +94,34 @@ static void prepareTimeseries() { * ============================================================ */ TEST_CASE("C API - Create timeseries", "[c_createTimeseries]") { - CaseReporter cr("c_createTimeseries"); - const char* path = "root.ctest.d1.s1"; - ensureTimeseries(g_session, path, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); - bool exists = false; - REQUIRE(ts_session_check_timeseries_exists(g_session, path, &exists) == TS_OK); - REQUIRE(exists); - REQUIRE(ts_session_delete_timeseries(g_session, path) == TS_OK); + CaseReporter cr("c_createTimeseries"); + const char* path = "root.ctest.d1.s1"; + ensureTimeseries(g_session, path, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); + bool exists = false; + REQUIRE(ts_session_check_timeseries_exists(g_session, path, &exists) == TS_OK); + REQUIRE(exists); + REQUIRE(ts_session_delete_timeseries(g_session, path) == TS_OK); } TEST_CASE("C API - Delete timeseries", "[c_deleteTimeseries]") { - CaseReporter cr("c_deleteTimeseries"); - const char* path = "root.ctest.d1.s1"; - ensureTimeseries(g_session, path, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); - REQUIRE(ts_session_delete_timeseries(g_session, path) == TS_OK); - bool exists = true; - REQUIRE(ts_session_check_timeseries_exists(g_session, path, &exists) == TS_OK); - REQUIRE_FALSE(exists); + CaseReporter cr("c_deleteTimeseries"); + const char* path = "root.ctest.d1.s1"; + ensureTimeseries(g_session, path, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); + REQUIRE(ts_session_delete_timeseries(g_session, path) == TS_OK); + bool exists = true; + REQUIRE(ts_session_check_timeseries_exists(g_session, path, &exists) == TS_OK); + REQUIRE_FALSE(exists); } TEST_CASE("C API - Login failure", "[c_Authentication]") { - CaseReporter cr("c_LoginTest"); - CSession* badSession = ts_session_new("127.0.0.1", 6667, "root", "wrong-password"); - REQUIRE(badSession != nullptr); - TsStatus status = ts_session_open(badSession); - REQUIRE(status != TS_OK); - const char* err = ts_get_last_error(); - REQUIRE(std::string(err).find("801") != std::string::npos); - ts_session_destroy(badSession); + CaseReporter cr("c_LoginTest"); + CSession* badSession = ts_session_new("127.0.0.1", 6667, "root", "wrong-password"); + REQUIRE(badSession != nullptr); + TsStatus status = ts_session_open(badSession); + REQUIRE(status != TS_OK); + const char* err = ts_get_last_error(); + REQUIRE(std::string(err).find("801") != std::string::npos); + ts_session_destroy(badSession); } /* ============================================================ @@ -127,34 +129,36 @@ TEST_CASE("C API - Login failure", "[c_Authentication]") { * ============================================================ */ TEST_CASE("C API - Insert record by string", "[c_insertRecordStr]") { - CaseReporter cr("c_insertRecordStr"); - prepareTimeseries(); - const char* deviceId = "root.ctest.d1"; - const char* measurements[] = {"s1", "s2", "s3"}; - - for (int64_t time = 0; time < 100; time++) { - const char* values[] = {"1", "2", "3"}; - TsStatus status = ts_session_insert_record_str(g_session, deviceId, time, 3, measurements, values); - REQUIRE(status == TS_OK); - } + CaseReporter cr("c_insertRecordStr"); + prepareTimeseries(); + const char* deviceId = "root.ctest.d1"; + const char* measurements[] = {"s1", "s2", "s3"}; - CSessionDataSet* dataSet = nullptr; - TsStatus status = ts_session_execute_query(g_session, "select s1,s2,s3 from root.ctest.d1", &dataSet); + for (int64_t time = 0; time < 100; time++) { + const char* values[] = {"1", "2", "3"}; + TsStatus status = + ts_session_insert_record_str(g_session, deviceId, time, 3, measurements, values); REQUIRE(status == TS_OK); - REQUIRE(dataSet != nullptr); - ts_dataset_set_fetch_size(dataSet, 1024); - int count = 0; - while (ts_dataset_has_next(dataSet)) { - CRowRecord* record = ts_dataset_next(dataSet); - REQUIRE(record != nullptr); - REQUIRE(ts_row_record_get_int64(record, 0) == 1); - REQUIRE(ts_row_record_get_int64(record, 1) == 2); - REQUIRE(ts_row_record_get_int64(record, 2) == 3); - ++count; - ts_row_record_destroy(record); - } - REQUIRE(count == 100); - ts_dataset_destroy(dataSet); + } + + CSessionDataSet* dataSet = nullptr; + TsStatus status = + ts_session_execute_query(g_session, "select s1,s2,s3 from root.ctest.d1", &dataSet); + REQUIRE(status == TS_OK); + REQUIRE(dataSet != nullptr); + ts_dataset_set_fetch_size(dataSet, 1024); + int count = 0; + while (ts_dataset_has_next(dataSet)) { + CRowRecord* record = ts_dataset_next(dataSet); + REQUIRE(record != nullptr); + REQUIRE(ts_row_record_get_int64(record, 0) == 1); + REQUIRE(ts_row_record_get_int64(record, 1) == 2); + REQUIRE(ts_row_record_get_int64(record, 2) == 3); + ++count; + ts_row_record_destroy(record); + } + REQUIRE(count == 100); + ts_dataset_destroy(dataSet); } /* ============================================================ @@ -162,30 +166,32 @@ TEST_CASE("C API - Insert record by string", "[c_insertRecordStr]") { * ============================================================ */ TEST_CASE("C API - Insert record with types", "[c_insertRecordTyped]") { - CaseReporter cr("c_insertRecordTyped"); - - const char* timeseries[] = {"root.ctest.d1.s1", "root.ctest.d1.s2", "root.ctest.d1.s3"}; - TSDataType_C types[] = {TS_TYPE_INT32, TS_TYPE_DOUBLE, TS_TYPE_INT64}; - TSEncoding_C encodings[] = {TS_ENCODING_RLE, TS_ENCODING_RLE, TS_ENCODING_RLE}; - TSCompressionType_C compressions[] = {TS_COMPRESSION_SNAPPY, TS_COMPRESSION_SNAPPY, TS_COMPRESSION_SNAPPY}; - - for (int i = 0; i < 3; i++) { - ensureTimeseries(g_session, timeseries[i], types[i], encodings[i], compressions[i]); - } - - const char* deviceId = "root.ctest.d1"; - const char* measurements[] = {"s1", "s2", "s3"}; - - for (int64_t time = 0; time < 100; time++) { - int32_t v1 = 1; - double v2 = 2.2; - int64_t v3 = 3; - const void* values[] = {&v1, &v2, &v3}; - TsStatus status = ts_session_insert_record(g_session, deviceId, time, 3, measurements, types, values); - REQUIRE(status == TS_OK); - } + CaseReporter cr("c_insertRecordTyped"); + + const char* timeseries[] = {"root.ctest.d1.s1", "root.ctest.d1.s2", "root.ctest.d1.s3"}; + TSDataType_C types[] = {TS_TYPE_INT32, TS_TYPE_DOUBLE, TS_TYPE_INT64}; + TSEncoding_C encodings[] = {TS_ENCODING_RLE, TS_ENCODING_RLE, TS_ENCODING_RLE}; + TSCompressionType_C compressions[] = {TS_COMPRESSION_SNAPPY, TS_COMPRESSION_SNAPPY, + TS_COMPRESSION_SNAPPY}; + + for (int i = 0; i < 3; i++) { + ensureTimeseries(g_session, timeseries[i], types[i], encodings[i], compressions[i]); + } + + const char* deviceId = "root.ctest.d1"; + const char* measurements[] = {"s1", "s2", "s3"}; + + for (int64_t time = 0; time < 100; time++) { + int32_t v1 = 1; + double v2 = 2.2; + int64_t v3 = 3; + const void* values[] = {&v1, &v2, &v3}; + TsStatus status = + ts_session_insert_record(g_session, deviceId, time, 3, measurements, types, values); + REQUIRE(status == TS_OK); + } - REQUIRE(queryRowCount(g_session, "select s1,s2,s3 from root.ctest.d1") == 100); + REQUIRE(queryRowCount(g_session, "select s1,s2,s3 from root.ctest.d1") == 100); } /* ============================================================ @@ -193,33 +199,33 @@ TEST_CASE("C API - Insert record with types", "[c_insertRecordTyped]") { * ============================================================ */ TEST_CASE("C API - Insert records batch", "[c_insertRecordsBatch]") { - CaseReporter cr("c_insertRecordsBatch"); - prepareTimeseries(); - - const int BATCH = 100; - const char* deviceId = "root.ctest.d1"; - const char* measurements[] = {"s1", "s2", "s3"}; - - const char* deviceIds[BATCH]; - int64_t times[BATCH]; - int measurementCounts[BATCH]; - const char* const* measurementsList[BATCH]; - const char* values[] = {"1", "2", "3"}; - const char* const* valuesList[BATCH]; - - for (int i = 0; i < BATCH; i++) { - deviceIds[i] = deviceId; - times[i] = i; - measurementCounts[i] = 3; - measurementsList[i] = measurements; - valuesList[i] = values; - } - - TsStatus status = ts_session_insert_records_str(g_session, BATCH, deviceIds, times, - measurementCounts, measurementsList, valuesList); - REQUIRE(status == TS_OK); - - REQUIRE(queryRowCount(g_session, "select s1,s2,s3 from root.ctest.d1") == BATCH); + CaseReporter cr("c_insertRecordsBatch"); + prepareTimeseries(); + + const int BATCH = 100; + const char* deviceId = "root.ctest.d1"; + const char* measurements[] = {"s1", "s2", "s3"}; + + const char* deviceIds[BATCH]; + int64_t times[BATCH]; + int measurementCounts[BATCH]; + const char* const* measurementsList[BATCH]; + const char* values[] = {"1", "2", "3"}; + const char* const* valuesList[BATCH]; + + for (int i = 0; i < BATCH; i++) { + deviceIds[i] = deviceId; + times[i] = i; + measurementCounts[i] = 3; + measurementsList[i] = measurements; + valuesList[i] = values; + } + + TsStatus status = ts_session_insert_records_str(g_session, BATCH, deviceIds, times, + measurementCounts, measurementsList, valuesList); + REQUIRE(status == TS_OK); + + REQUIRE(queryRowCount(g_session, "select s1,s2,s3 from root.ctest.d1") == BATCH); } /* ============================================================ @@ -227,43 +233,44 @@ TEST_CASE("C API - Insert records batch", "[c_insertRecordsBatch]") { * ============================================================ */ TEST_CASE("C API - Insert tablet", "[c_insertTablet]") { - CaseReporter cr("c_insertTablet"); - prepareTimeseries(); + CaseReporter cr("c_insertTablet"); + prepareTimeseries(); - const char* columnNames[] = {"s1", "s2", "s3"}; - TSDataType_C dataTypes[] = {TS_TYPE_INT64, TS_TYPE_INT64, TS_TYPE_INT64}; + const char* columnNames[] = {"s1", "s2", "s3"}; + TSDataType_C dataTypes[] = {TS_TYPE_INT64, TS_TYPE_INT64, TS_TYPE_INT64}; - CTablet* tablet = ts_tablet_new("root.ctest.d1", 3, columnNames, dataTypes, 100); - REQUIRE(tablet != nullptr); + CTablet* tablet = ts_tablet_new("root.ctest.d1", 3, columnNames, dataTypes, 100); + REQUIRE(tablet != nullptr); - for (int64_t time = 0; time < 100; time++) { - ts_tablet_add_timestamp(tablet, (int)time, time); - for (int col = 0; col < 3; col++) { - int64_t val = col; - ts_tablet_add_value_int64(tablet, col, (int)time, val); - } + for (int64_t time = 0; time < 100; time++) { + ts_tablet_add_timestamp(tablet, (int)time, time); + for (int col = 0; col < 3; col++) { + int64_t val = col; + ts_tablet_add_value_int64(tablet, col, (int)time, val); } - ts_tablet_set_row_count(tablet, 100); - - TsStatus status = ts_session_insert_tablet(g_session, tablet, false); - REQUIRE(status == TS_OK); - - CSessionDataSet* dataSet = nullptr; - REQUIRE(ts_session_execute_query(g_session, "select s1,s2,s3 from root.ctest.d1", &dataSet) == TS_OK); - REQUIRE(dataSet != nullptr); - ts_dataset_set_fetch_size(dataSet, 1024); - int count = 0; - while (ts_dataset_has_next(dataSet)) { - CRowRecord* record = ts_dataset_next(dataSet); - REQUIRE(ts_row_record_get_int64(record, 0) == 0); - REQUIRE(ts_row_record_get_int64(record, 1) == 1); - REQUIRE(ts_row_record_get_int64(record, 2) == 2); - ++count; - ts_row_record_destroy(record); - } - REQUIRE(count == 100); - ts_dataset_destroy(dataSet); - ts_tablet_destroy(tablet); + } + ts_tablet_set_row_count(tablet, 100); + + TsStatus status = ts_session_insert_tablet(g_session, tablet, false); + REQUIRE(status == TS_OK); + + CSessionDataSet* dataSet = nullptr; + REQUIRE(ts_session_execute_query(g_session, "select s1,s2,s3 from root.ctest.d1", &dataSet) == + TS_OK); + REQUIRE(dataSet != nullptr); + ts_dataset_set_fetch_size(dataSet, 1024); + int count = 0; + while (ts_dataset_has_next(dataSet)) { + CRowRecord* record = ts_dataset_next(dataSet); + REQUIRE(ts_row_record_get_int64(record, 0) == 0); + REQUIRE(ts_row_record_get_int64(record, 1) == 1); + REQUIRE(ts_row_record_get_int64(record, 2) == 2); + ++count; + ts_row_record_destroy(record); + } + REQUIRE(count == 100); + ts_dataset_destroy(dataSet); + ts_tablet_destroy(tablet); } /* ============================================================ @@ -271,20 +278,20 @@ TEST_CASE("C API - Insert tablet", "[c_insertTablet]") { * ============================================================ */ TEST_CASE("C API - Execute non-query SQL", "[c_executeNonQuery]") { - CaseReporter cr("c_executeNonQuery"); - prepareTimeseries(); - - TsStatus status = ts_session_execute_non_query(g_session, - "insert into root.ctest.d1(timestamp,s1,s2,s3) values(200,10,20,30)"); - REQUIRE(status == TS_OK); - - CSessionDataSet* dataSet = nullptr; - ts_session_execute_query(g_session, "select s1 from root.ctest.d1 where time=200", &dataSet); - REQUIRE(ts_dataset_has_next(dataSet)); - CRowRecord* record = ts_dataset_next(dataSet); - REQUIRE(ts_row_record_get_int64(record, 0) == 10); - ts_row_record_destroy(record); - ts_dataset_destroy(dataSet); + CaseReporter cr("c_executeNonQuery"); + prepareTimeseries(); + + TsStatus status = ts_session_execute_non_query( + g_session, "insert into root.ctest.d1(timestamp,s1,s2,s3) values(200,10,20,30)"); + REQUIRE(status == TS_OK); + + CSessionDataSet* dataSet = nullptr; + ts_session_execute_query(g_session, "select s1 from root.ctest.d1 where time=200", &dataSet); + REQUIRE(ts_dataset_has_next(dataSet)); + CRowRecord* record = ts_dataset_next(dataSet); + REQUIRE(ts_row_record_get_int64(record, 0) == 10); + ts_row_record_destroy(record); + ts_dataset_destroy(dataSet); } /* ============================================================ @@ -292,30 +299,30 @@ TEST_CASE("C API - Execute non-query SQL", "[c_executeNonQuery]") { * ============================================================ */ TEST_CASE("C API - Execute raw data query", "[c_executeRawDataQuery]") { - CaseReporter cr("c_executeRawDataQuery"); - prepareTimeseries(); + CaseReporter cr("c_executeRawDataQuery"); + prepareTimeseries(); - const char* deviceId = "root.ctest.d1"; - const char* measurements[] = {"s1", "s2", "s3"}; + const char* deviceId = "root.ctest.d1"; + const char* measurements[] = {"s1", "s2", "s3"}; - for (int64_t time = 0; time < 50; time++) { - const char* values[] = {"1", "2", "3"}; - ts_session_insert_record_str(g_session, deviceId, time, 3, measurements, values); - } + for (int64_t time = 0; time < 50; time++) { + const char* values[] = {"1", "2", "3"}; + ts_session_insert_record_str(g_session, deviceId, time, 3, measurements, values); + } - const char* paths[] = {"root.ctest.d1.s1", "root.ctest.d1.s2", "root.ctest.d1.s3"}; - CSessionDataSet* dataSet = nullptr; - TsStatus status = ts_session_execute_raw_data_query(g_session, 3, paths, 0, 50, &dataSet); - REQUIRE(status == TS_OK); + const char* paths[] = {"root.ctest.d1.s1", "root.ctest.d1.s2", "root.ctest.d1.s3"}; + CSessionDataSet* dataSet = nullptr; + TsStatus status = ts_session_execute_raw_data_query(g_session, 3, paths, 0, 50, &dataSet); + REQUIRE(status == TS_OK); - int count = 0; - while (ts_dataset_has_next(dataSet)) { - CRowRecord* record = ts_dataset_next(dataSet); - count++; - ts_row_record_destroy(record); - } - REQUIRE(count == 50); - ts_dataset_destroy(dataSet); + int count = 0; + while (ts_dataset_has_next(dataSet)) { + CRowRecord* record = ts_dataset_next(dataSet); + count++; + ts_row_record_destroy(record); + } + REQUIRE(count == 50); + ts_dataset_destroy(dataSet); } /* ============================================================ @@ -323,21 +330,21 @@ TEST_CASE("C API - Execute raw data query", "[c_executeRawDataQuery]") { * ============================================================ */ TEST_CASE("C API - Delete data", "[c_deleteData]") { - CaseReporter cr("c_deleteData"); - prepareTimeseries(); + CaseReporter cr("c_deleteData"); + prepareTimeseries(); - const char* deviceId = "root.ctest.d1"; - const char* measurements[] = {"s1", "s2", "s3"}; - for (int64_t time = 0; time < 100; time++) { - const char* values[] = {"1", "2", "3"}; - ts_session_insert_record_str(g_session, deviceId, time, 3, measurements, values); - } + const char* deviceId = "root.ctest.d1"; + const char* measurements[] = {"s1", "s2", "s3"}; + for (int64_t time = 0; time < 100; time++) { + const char* values[] = {"1", "2", "3"}; + ts_session_insert_record_str(g_session, deviceId, time, 3, measurements, values); + } - const char* paths[] = {"root.ctest.d1.s1", "root.ctest.d1.s2", "root.ctest.d1.s3"}; - TsStatus status = ts_session_delete_data_batch(g_session, 3, paths, 49); - REQUIRE(status == TS_OK); + const char* paths[] = {"root.ctest.d1.s1", "root.ctest.d1.s2", "root.ctest.d1.s3"}; + TsStatus status = ts_session_delete_data_batch(g_session, 3, paths, 49); + REQUIRE(status == TS_OK); - REQUIRE(queryRowCount(g_session, "select s1,s2,s3 from root.ctest.d1") == 50); + REQUIRE(queryRowCount(g_session, "select s1,s2,s3 from root.ctest.d1") == 50); } /* ============================================================ @@ -345,18 +352,18 @@ TEST_CASE("C API - Delete data", "[c_deleteData]") { * ============================================================ */ TEST_CASE("C API - Timezone", "[c_timezone]") { - CaseReporter cr("c_timezone"); - char buf[64] = {0}; - TsStatus status = ts_session_get_timezone(g_session, buf, sizeof(buf)); - REQUIRE(status == TS_OK); - REQUIRE(strlen(buf) > 0); - - status = ts_session_set_timezone(g_session, "Asia/Shanghai"); - REQUIRE(status == TS_OK); - - memset(buf, 0, sizeof(buf)); - ts_session_get_timezone(g_session, buf, sizeof(buf)); - REQUIRE(std::string(buf) == "Asia/Shanghai"); + CaseReporter cr("c_timezone"); + char buf[64] = {0}; + TsStatus status = ts_session_get_timezone(g_session, buf, sizeof(buf)); + REQUIRE(status == TS_OK); + REQUIRE(strlen(buf) > 0); + + status = ts_session_set_timezone(g_session, "Asia/Shanghai"); + REQUIRE(status == TS_OK); + + memset(buf, 0, sizeof(buf)); + ts_session_get_timezone(g_session, buf, sizeof(buf)); + REQUIRE(std::string(buf) == "Asia/Shanghai"); } /* ============================================================ @@ -364,23 +371,23 @@ TEST_CASE("C API - Timezone", "[c_timezone]") { * ============================================================ */ TEST_CASE("C API - Multi-node session", "[c_multiNode]") { - CaseReporter cr("c_multiNode"); - const char* urls[] = {"127.0.0.1:6667"}; - CSession* localSession = ts_session_new_multi_node(urls, 1, "root", "root"); - REQUIRE(localSession != nullptr); - - TsStatus status = ts_session_open(localSession); - REQUIRE(status == TS_OK); - - const char* path = "root.ctest.d1.s1"; - ensureTimeseries(localSession, path, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); - bool exists = false; - REQUIRE(ts_session_check_timeseries_exists(localSession, path, &exists) == TS_OK); - REQUIRE(exists); - REQUIRE(ts_session_delete_timeseries(localSession, path) == TS_OK); - - ts_session_close(localSession); - ts_session_destroy(localSession); + CaseReporter cr("c_multiNode"); + const char* urls[] = {"127.0.0.1:6667"}; + CSession* localSession = ts_session_new_multi_node(urls, 1, "root", "root"); + REQUIRE(localSession != nullptr); + + TsStatus status = ts_session_open(localSession); + REQUIRE(status == TS_OK); + + const char* path = "root.ctest.d1.s1"; + ensureTimeseries(localSession, path, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); + bool exists = false; + REQUIRE(ts_session_check_timeseries_exists(localSession, path, &exists) == TS_OK); + REQUIRE(exists); + REQUIRE(ts_session_delete_timeseries(localSession, path) == TS_OK); + + ts_session_close(localSession); + ts_session_destroy(localSession); } /* ============================================================ @@ -388,32 +395,32 @@ TEST_CASE("C API - Multi-node session", "[c_multiNode]") { * ============================================================ */ TEST_CASE("C API - Dataset column info", "[c_datasetColumns]") { - CaseReporter cr("c_datasetColumns"); - prepareTimeseries(); + CaseReporter cr("c_datasetColumns"); + prepareTimeseries(); - const char* deviceId = "root.ctest.d1"; - const char* measurements[] = {"s1", "s2", "s3"}; - const char* values[] = {"1", "2", "3"}; - ts_session_insert_record_str(g_session, deviceId, 0, 3, measurements, values); + const char* deviceId = "root.ctest.d1"; + const char* measurements[] = {"s1", "s2", "s3"}; + const char* values[] = {"1", "2", "3"}; + ts_session_insert_record_str(g_session, deviceId, 0, 3, measurements, values); - CSessionDataSet* dataSet = nullptr; - ts_session_execute_query(g_session, "select s1,s2,s3 from root.ctest.d1", &dataSet); - REQUIRE(dataSet != nullptr); + CSessionDataSet* dataSet = nullptr; + ts_session_execute_query(g_session, "select s1,s2,s3 from root.ctest.d1", &dataSet); + REQUIRE(dataSet != nullptr); - int colCount = ts_dataset_get_column_count(dataSet); - REQUIRE(colCount == 4); // Time + s1 + s2 + s3 + int colCount = ts_dataset_get_column_count(dataSet); + REQUIRE(colCount == 4); // Time + s1 + s2 + s3 - const char* col0 = ts_dataset_get_column_name(dataSet, 0); - REQUIRE(std::string(col0) == "Time"); + const char* col0 = ts_dataset_get_column_name(dataSet, 0); + REQUIRE(std::string(col0) == "Time"); - int n = ts_dataset_get_column_count(dataSet); - for (int i = 0; i < n; i++) { - const char* ct = ts_dataset_get_column_type(dataSet, i); - REQUIRE(ct != nullptr); - REQUIRE(strlen(ct) > 0); - } + int n = ts_dataset_get_column_count(dataSet); + for (int i = 0; i < n; i++) { + const char* ct = ts_dataset_get_column_type(dataSet, i); + REQUIRE(ct != nullptr); + REQUIRE(strlen(ct) > 0); + } - ts_dataset_destroy(dataSet); + ts_dataset_destroy(dataSet); } /* ============================================================ @@ -421,313 +428,320 @@ TEST_CASE("C API - Dataset column info", "[c_datasetColumns]") { * ============================================================ */ TEST_CASE("C API - Session lifecycle variants", "[c_sessionLifecycle]") { - CaseReporter cr("c_sessionLifecycle"); - - CSession* s1 = ts_session_new_with_zone("127.0.0.1", 6667, "root", "root", "Asia/Shanghai", 1024); - REQUIRE(s1 != nullptr); - REQUIRE(ts_session_open(s1) == TS_OK); - ts_session_close(s1); - ts_session_destroy(s1); - - CSession* s2 = ts_session_new("127.0.0.1", 6667, "root", "root"); - REQUIRE(s2 != nullptr); - REQUIRE(ts_session_open_with_compression(s2, true) == TS_OK); - ts_session_close(s2); - ts_session_destroy(s2); + CaseReporter cr("c_sessionLifecycle"); + + CSession* s1 = ts_session_new_with_zone("127.0.0.1", 6667, "root", "root", "Asia/Shanghai", 1024); + REQUIRE(s1 != nullptr); + REQUIRE(ts_session_open(s1) == TS_OK); + ts_session_close(s1); + ts_session_destroy(s1); + + CSession* s2 = ts_session_new("127.0.0.1", 6667, "root", "root"); + REQUIRE(s2 != nullptr); + REQUIRE(ts_session_open_with_compression(s2, true) == TS_OK); + ts_session_close(s2); + ts_session_destroy(s2); } TEST_CASE("C API - Database and extended timeseries APIs", "[c_dbTimeseries]") { - CaseReporter cr("c_dbTimeseries"); - - const char* sg1 = "root.cov_sg_a"; - const char* sg2 = "root.cov_sg_b"; - dropDatabaseIfExists(g_session, sg1); - dropDatabaseIfExists(g_session, sg2); - REQUIRE(ts_session_create_database(g_session, sg1) == TS_OK); - REQUIRE(ts_session_create_database(g_session, sg2) == TS_OK); - const char* dbs[] = {sg1, sg2}; - REQUIRE(ts_session_delete_databases(g_session, dbs, 2) == TS_OK); - - const char* sg3 = "root.cov_sg_c"; - dropDatabaseIfExists(g_session, sg3); - REQUIRE(ts_session_create_database(g_session, sg3) == TS_OK); - REQUIRE(ts_session_delete_database(g_session, sg3) == TS_OK); - - const char* sgEx = "root.cov_sg_ex"; - dropDatabaseIfExists(g_session, sgEx); - REQUIRE(ts_session_create_database(g_session, sgEx) == TS_OK); - - const char* pathEx = "root.cov_sg_ex.d1.s_ex"; - dropTimeseriesIfExists(g_session, pathEx); - REQUIRE(ts_session_create_timeseries_ex( - g_session, pathEx, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY, 0, nullptr, nullptr, 0, - nullptr, nullptr, 0, nullptr, nullptr, nullptr) == TS_OK); - - const char* pathsM[] = {"root.cov_sg_ex.d1.s_m1", "root.cov_sg_ex.d1.s_m2"}; - TSDataType_C tsM[] = {TS_TYPE_INT64, TS_TYPE_DOUBLE}; - TSEncoding_C encM[] = {TS_ENCODING_RLE, TS_ENCODING_RLE}; - TSCompressionType_C compM[] = {TS_COMPRESSION_SNAPPY, TS_COMPRESSION_SNAPPY}; - for (int i = 0; i < 2; i++) { - dropTimeseriesIfExists(g_session, pathsM[i]); - } - REQUIRE(ts_session_create_multi_timeseries(g_session, 2, pathsM, tsM, encM, compM) == TS_OK); - REQUIRE(ts_session_delete_timeseries_batch(g_session, pathsM, 2) == TS_OK); - REQUIRE(ts_session_delete_timeseries(g_session, pathEx) == TS_OK); - REQUIRE(ts_session_delete_database(g_session, sgEx) == TS_OK); + CaseReporter cr("c_dbTimeseries"); + + const char* sg1 = "root.cov_sg_a"; + const char* sg2 = "root.cov_sg_b"; + dropDatabaseIfExists(g_session, sg1); + dropDatabaseIfExists(g_session, sg2); + REQUIRE(ts_session_create_database(g_session, sg1) == TS_OK); + REQUIRE(ts_session_create_database(g_session, sg2) == TS_OK); + const char* dbs[] = {sg1, sg2}; + REQUIRE(ts_session_delete_databases(g_session, dbs, 2) == TS_OK); + + const char* sg3 = "root.cov_sg_c"; + dropDatabaseIfExists(g_session, sg3); + REQUIRE(ts_session_create_database(g_session, sg3) == TS_OK); + REQUIRE(ts_session_delete_database(g_session, sg3) == TS_OK); + + const char* sgEx = "root.cov_sg_ex"; + dropDatabaseIfExists(g_session, sgEx); + REQUIRE(ts_session_create_database(g_session, sgEx) == TS_OK); + + const char* pathEx = "root.cov_sg_ex.d1.s_ex"; + dropTimeseriesIfExists(g_session, pathEx); + REQUIRE(ts_session_create_timeseries_ex(g_session, pathEx, TS_TYPE_INT64, TS_ENCODING_RLE, + TS_COMPRESSION_SNAPPY, 0, nullptr, nullptr, 0, nullptr, + nullptr, 0, nullptr, nullptr, nullptr) == TS_OK); + + const char* pathsM[] = {"root.cov_sg_ex.d1.s_m1", "root.cov_sg_ex.d1.s_m2"}; + TSDataType_C tsM[] = {TS_TYPE_INT64, TS_TYPE_DOUBLE}; + TSEncoding_C encM[] = {TS_ENCODING_RLE, TS_ENCODING_RLE}; + TSCompressionType_C compM[] = {TS_COMPRESSION_SNAPPY, TS_COMPRESSION_SNAPPY}; + for (int i = 0; i < 2; i++) { + dropTimeseriesIfExists(g_session, pathsM[i]); + } + REQUIRE(ts_session_create_multi_timeseries(g_session, 2, pathsM, tsM, encM, compM) == TS_OK); + REQUIRE(ts_session_delete_timeseries_batch(g_session, pathsM, 2) == TS_OK); + REQUIRE(ts_session_delete_timeseries(g_session, pathEx) == TS_OK); + REQUIRE(ts_session_delete_database(g_session, sgEx) == TS_OK); } TEST_CASE("C API - Tablet row count and reset", "[c_tabletReset]") { - CaseReporter cr("c_tabletReset"); - const char* colNames[] = {"s1"}; - TSDataType_C dts[] = {TS_TYPE_INT64}; - CTablet* tablet = ts_tablet_new("root.ctest.d1", 1, colNames, dts, 10); - REQUIRE(tablet != nullptr); - REQUIRE(ts_tablet_get_row_count(tablet) == 0); - REQUIRE(ts_tablet_set_row_count(tablet, 1) == TS_OK); - REQUIRE(ts_tablet_get_row_count(tablet) == 1); - ts_tablet_reset(tablet); - REQUIRE(ts_tablet_get_row_count(tablet) == 0); - ts_tablet_destroy(tablet); + CaseReporter cr("c_tabletReset"); + const char* colNames[] = {"s1"}; + TSDataType_C dts[] = {TS_TYPE_INT64}; + CTablet* tablet = ts_tablet_new("root.ctest.d1", 1, colNames, dts, 10); + REQUIRE(tablet != nullptr); + REQUIRE(ts_tablet_get_row_count(tablet) == 0); + REQUIRE(ts_tablet_set_row_count(tablet, 1) == TS_OK); + REQUIRE(ts_tablet_get_row_count(tablet) == 1); + ts_tablet_reset(tablet); + REQUIRE(ts_tablet_get_row_count(tablet) == 0); + ts_tablet_destroy(tablet); } TEST_CASE("C API - Aligned timeseries and aligned writes", "[c_aligned]") { - CaseReporter cr("c_aligned"); - - const char* sg = "root.cov_al"; - dropDatabaseIfExists(g_session, sg); - REQUIRE(ts_session_create_database(g_session, sg) == TS_OK); - - const char* alDev = "root.cov_al.dev"; - const char* meas[] = {"m1", "m2"}; - TSDataType_C adt[] = {TS_TYPE_INT64, TS_TYPE_INT64}; - TSEncoding_C aenc[] = {TS_ENCODING_RLE, TS_ENCODING_RLE}; - TSCompressionType_C acomp[] = {TS_COMPRESSION_SNAPPY, TS_COMPRESSION_SNAPPY}; - REQUIRE(ts_session_create_aligned_timeseries(g_session, alDev, 2, meas, adt, aenc, acomp) == TS_OK); - - const char* mstr[] = {"m1", "m2"}; - const char* vstr[] = {"1", "2"}; - REQUIRE(ts_session_insert_aligned_record_str(g_session, alDev, 100LL, 2, mstr, vstr) == TS_OK); - - int64_t v1 = 3; - int64_t v2 = 4; - const void* vals[] = {&v1, &v2}; - REQUIRE(ts_session_insert_aligned_record(g_session, alDev, 101LL, 2, mstr, adt, vals) == TS_OK); - - const char* devs1[] = {alDev}; - int64_t times1[] = {102LL}; - int mc1[] = {2}; - const char* const* mlist1[] = {mstr}; - const char* const* vlist1[] = {vstr}; - REQUIRE(ts_session_insert_aligned_records_str(g_session, 1, devs1, times1, mc1, mlist1, vlist1) == TS_OK); - - const TSDataType_C* trows[] = {adt}; - const void* const* vrows[] = {vals}; - REQUIRE(ts_session_insert_aligned_records(g_session, 1, devs1, times1, mc1, mlist1, trows, vrows) == TS_OK); - - int64_t tRows[] = {104LL, 105LL}; - int mcRows[] = {2, 2}; - const char* const* mRows[] = {mstr, mstr}; - const TSDataType_C* tRowsList[] = {adt, adt}; - int64_t v1a = 5, v1b = 6; - int64_t v2a = 7, v2b = 8; - const void* row0[] = {&v1a, &v2a}; - const void* row1[] = {&v1b, &v2b}; - const void* const* vRowsList[] = {row0, row1}; - REQUIRE(ts_session_insert_aligned_records_of_one_device(g_session, alDev, 2, tRows, mcRows, mRows, tRowsList, - vRowsList, true) == TS_OK); - - const char* alDev2 = "root.cov_al.dev2"; - REQUIRE(ts_session_create_aligned_timeseries(g_session, alDev2, 2, meas, adt, aenc, acomp) == TS_OK); - CTablet* tab = ts_tablet_new(alDev, 2, meas, adt, 10); - CTablet* tab2 = ts_tablet_new(alDev2, 2, meas, adt, 5); - REQUIRE(tab != nullptr); - REQUIRE(tab2 != nullptr); - ts_tablet_add_timestamp(tab, 0, 106LL); - ts_tablet_add_value_int64(tab, 0, 0, 9); - ts_tablet_add_value_int64(tab, 1, 0, 10); - ts_tablet_set_row_count(tab, 1); - ts_tablet_add_timestamp(tab2, 0, 107LL); - ts_tablet_add_value_int64(tab2, 0, 0, 11); - ts_tablet_add_value_int64(tab2, 1, 0, 12); - ts_tablet_set_row_count(tab2, 1); - const char* devIds[] = {alDev, alDev2}; - CTablet* tabs[] = {tab, tab2}; - REQUIRE(ts_session_insert_aligned_tablets(g_session, 2, devIds, tabs, false) == TS_OK); - - ts_tablet_reset(tab); - ts_tablet_add_timestamp(tab, 0, 200LL); - ts_tablet_add_value_int64(tab, 0, 0, 13); - ts_tablet_add_value_int64(tab, 1, 0, 14); - ts_tablet_set_row_count(tab, 1); - REQUIRE(ts_session_insert_aligned_tablet(g_session, tab, false) == TS_OK); - - ts_tablet_destroy(tab2); - ts_tablet_destroy(tab); - - REQUIRE(ts_session_delete_database(g_session, sg) == TS_OK); + CaseReporter cr("c_aligned"); + + const char* sg = "root.cov_al"; + dropDatabaseIfExists(g_session, sg); + REQUIRE(ts_session_create_database(g_session, sg) == TS_OK); + + const char* alDev = "root.cov_al.dev"; + const char* meas[] = {"m1", "m2"}; + TSDataType_C adt[] = {TS_TYPE_INT64, TS_TYPE_INT64}; + TSEncoding_C aenc[] = {TS_ENCODING_RLE, TS_ENCODING_RLE}; + TSCompressionType_C acomp[] = {TS_COMPRESSION_SNAPPY, TS_COMPRESSION_SNAPPY}; + REQUIRE(ts_session_create_aligned_timeseries(g_session, alDev, 2, meas, adt, aenc, acomp) == + TS_OK); + + const char* mstr[] = {"m1", "m2"}; + const char* vstr[] = {"1", "2"}; + REQUIRE(ts_session_insert_aligned_record_str(g_session, alDev, 100LL, 2, mstr, vstr) == TS_OK); + + int64_t v1 = 3; + int64_t v2 = 4; + const void* vals[] = {&v1, &v2}; + REQUIRE(ts_session_insert_aligned_record(g_session, alDev, 101LL, 2, mstr, adt, vals) == TS_OK); + + const char* devs1[] = {alDev}; + int64_t times1[] = {102LL}; + int mc1[] = {2}; + const char* const* mlist1[] = {mstr}; + const char* const* vlist1[] = {vstr}; + REQUIRE(ts_session_insert_aligned_records_str(g_session, 1, devs1, times1, mc1, mlist1, vlist1) == + TS_OK); + + const TSDataType_C* trows[] = {adt}; + const void* const* vrows[] = {vals}; + REQUIRE(ts_session_insert_aligned_records(g_session, 1, devs1, times1, mc1, mlist1, trows, + vrows) == TS_OK); + + int64_t tRows[] = {104LL, 105LL}; + int mcRows[] = {2, 2}; + const char* const* mRows[] = {mstr, mstr}; + const TSDataType_C* tRowsList[] = {adt, adt}; + int64_t v1a = 5, v1b = 6; + int64_t v2a = 7, v2b = 8; + const void* row0[] = {&v1a, &v2a}; + const void* row1[] = {&v1b, &v2b}; + const void* const* vRowsList[] = {row0, row1}; + REQUIRE(ts_session_insert_aligned_records_of_one_device(g_session, alDev, 2, tRows, mcRows, mRows, + tRowsList, vRowsList, true) == TS_OK); + + const char* alDev2 = "root.cov_al.dev2"; + REQUIRE(ts_session_create_aligned_timeseries(g_session, alDev2, 2, meas, adt, aenc, acomp) == + TS_OK); + CTablet* tab = ts_tablet_new(alDev, 2, meas, adt, 10); + CTablet* tab2 = ts_tablet_new(alDev2, 2, meas, adt, 5); + REQUIRE(tab != nullptr); + REQUIRE(tab2 != nullptr); + ts_tablet_add_timestamp(tab, 0, 106LL); + ts_tablet_add_value_int64(tab, 0, 0, 9); + ts_tablet_add_value_int64(tab, 1, 0, 10); + ts_tablet_set_row_count(tab, 1); + ts_tablet_add_timestamp(tab2, 0, 107LL); + ts_tablet_add_value_int64(tab2, 0, 0, 11); + ts_tablet_add_value_int64(tab2, 1, 0, 12); + ts_tablet_set_row_count(tab2, 1); + const char* devIds[] = {alDev, alDev2}; + CTablet* tabs[] = {tab, tab2}; + REQUIRE(ts_session_insert_aligned_tablets(g_session, 2, devIds, tabs, false) == TS_OK); + + ts_tablet_reset(tab); + ts_tablet_add_timestamp(tab, 0, 200LL); + ts_tablet_add_value_int64(tab, 0, 0, 13); + ts_tablet_add_value_int64(tab, 1, 0, 14); + ts_tablet_set_row_count(tab, 1); + REQUIRE(ts_session_insert_aligned_tablet(g_session, tab, false) == TS_OK); + + ts_tablet_destroy(tab2); + ts_tablet_destroy(tab); + + REQUIRE(ts_session_delete_database(g_session, sg) == TS_OK); } TEST_CASE("C API - Typed batch inserts and insert_tablets", "[c_batchTablet]") { - CaseReporter cr("c_batchTablet"); - - const char* sg = "root.cov_batch"; - dropDatabaseIfExists(g_session, sg); - REQUIRE(ts_session_create_database(g_session, sg) == TS_OK); - - const char* p1 = "root.cov_batch.da.s1"; - const char* p2 = "root.cov_batch.db.s1"; - ensureTimeseries(g_session, p1, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); - ensureTimeseries(g_session, p2, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); - - const char* devIds[] = {"root.cov_batch.da", "root.cov_batch.db"}; - int64_t tt[] = {1LL, 2LL}; - int mmc[] = {1, 1}; - const char* mda[] = {"s1"}; - const char* mdb[] = {"s1"}; - const char* const* mlist[] = {mda, mdb}; - int64_t va = 11; - int64_t vb = 22; - const void* vva[] = {&va}; - const void* vvb[] = {&vb}; - const void* const* vlist[] = {vva, vvb}; - TSDataType_C ta[] = {TS_TYPE_INT64}; - TSDataType_C tb[] = {TS_TYPE_INT64}; - const TSDataType_C* tlist[] = {ta, tb}; - REQUIRE(ts_session_insert_records(g_session, 2, devIds, tt, mmc, mlist, tlist, vlist) == TS_OK); - - const char* dc = "root.cov_batch.dc"; - const char* p3 = "root.cov_batch.dc.s1"; - ensureTimeseries(g_session, p3, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); - int64_t tdc[] = {3LL, 4LL}; - int mcdc[] = {1, 1}; - const char* const* mdcList[] = {mda, mda}; - const TSDataType_C* tdcList[] = {ta, ta}; - int64_t vc = 30, vd = 40; - const void* rv0[] = {&vc}; - const void* rv1[] = {&vd}; - const void* const* vdcList[] = {rv0, rv1}; - REQUIRE(ts_session_insert_records_of_one_device(g_session, dc, 2, tdc, mcdc, mdcList, tdcList, vdcList, true) == - TS_OK); - - const char* col1[] = {"s1"}; - TSDataType_C dt1[] = {TS_TYPE_INT64}; - CTablet* tb1 = ts_tablet_new("root.cov_batch.ta", 1, col1, dt1, 5); - CTablet* tb2 = ts_tablet_new("root.cov_batch.tb", 1, col1, dt1, 5); - REQUIRE(tb1 != nullptr); - REQUIRE(tb2 != nullptr); - const char* pta = "root.cov_batch.ta.s1"; - const char* ptb = "root.cov_batch.tb.s1"; - ensureTimeseries(g_session, pta, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); - ensureTimeseries(g_session, ptb, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); - ts_tablet_add_timestamp(tb1, 0, 1LL); - ts_tablet_add_value_int64(tb1, 0, 0, 100); - ts_tablet_set_row_count(tb1, 1); - ts_tablet_add_timestamp(tb2, 0, 2LL); - ts_tablet_add_value_int64(tb2, 0, 0, 200); - ts_tablet_set_row_count(tb2, 1); - const char* tabDevs[] = {"root.cov_batch.ta", "root.cov_batch.tb"}; - CTablet* tbs[] = {tb1, tb2}; - REQUIRE(ts_session_insert_tablets(g_session, 2, tabDevs, tbs, false) == TS_OK); - ts_tablet_destroy(tb2); - ts_tablet_destroy(tb1); - - REQUIRE(ts_session_delete_database(g_session, sg) == TS_OK); + CaseReporter cr("c_batchTablet"); + + const char* sg = "root.cov_batch"; + dropDatabaseIfExists(g_session, sg); + REQUIRE(ts_session_create_database(g_session, sg) == TS_OK); + + const char* p1 = "root.cov_batch.da.s1"; + const char* p2 = "root.cov_batch.db.s1"; + ensureTimeseries(g_session, p1, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); + ensureTimeseries(g_session, p2, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); + + const char* devIds[] = {"root.cov_batch.da", "root.cov_batch.db"}; + int64_t tt[] = {1LL, 2LL}; + int mmc[] = {1, 1}; + const char* mda[] = {"s1"}; + const char* mdb[] = {"s1"}; + const char* const* mlist[] = {mda, mdb}; + int64_t va = 11; + int64_t vb = 22; + const void* vva[] = {&va}; + const void* vvb[] = {&vb}; + const void* const* vlist[] = {vva, vvb}; + TSDataType_C ta[] = {TS_TYPE_INT64}; + TSDataType_C tb[] = {TS_TYPE_INT64}; + const TSDataType_C* tlist[] = {ta, tb}; + REQUIRE(ts_session_insert_records(g_session, 2, devIds, tt, mmc, mlist, tlist, vlist) == TS_OK); + + const char* dc = "root.cov_batch.dc"; + const char* p3 = "root.cov_batch.dc.s1"; + ensureTimeseries(g_session, p3, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); + int64_t tdc[] = {3LL, 4LL}; + int mcdc[] = {1, 1}; + const char* const* mdcList[] = {mda, mda}; + const TSDataType_C* tdcList[] = {ta, ta}; + int64_t vc = 30, vd = 40; + const void* rv0[] = {&vc}; + const void* rv1[] = {&vd}; + const void* const* vdcList[] = {rv0, rv1}; + REQUIRE(ts_session_insert_records_of_one_device(g_session, dc, 2, tdc, mcdc, mdcList, tdcList, + vdcList, true) == TS_OK); + + const char* col1[] = {"s1"}; + TSDataType_C dt1[] = {TS_TYPE_INT64}; + CTablet* tb1 = ts_tablet_new("root.cov_batch.ta", 1, col1, dt1, 5); + CTablet* tb2 = ts_tablet_new("root.cov_batch.tb", 1, col1, dt1, 5); + REQUIRE(tb1 != nullptr); + REQUIRE(tb2 != nullptr); + const char* pta = "root.cov_batch.ta.s1"; + const char* ptb = "root.cov_batch.tb.s1"; + ensureTimeseries(g_session, pta, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); + ensureTimeseries(g_session, ptb, TS_TYPE_INT64, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY); + ts_tablet_add_timestamp(tb1, 0, 1LL); + ts_tablet_add_value_int64(tb1, 0, 0, 100); + ts_tablet_set_row_count(tb1, 1); + ts_tablet_add_timestamp(tb2, 0, 2LL); + ts_tablet_add_value_int64(tb2, 0, 0, 200); + ts_tablet_set_row_count(tb2, 1); + const char* tabDevs[] = {"root.cov_batch.ta", "root.cov_batch.tb"}; + CTablet* tbs[] = {tb1, tb2}; + REQUIRE(ts_session_insert_tablets(g_session, 2, tabDevs, tbs, false) == TS_OK); + ts_tablet_destroy(tb2); + ts_tablet_destroy(tb1); + + REQUIRE(ts_session_delete_database(g_session, sg) == TS_OK); } TEST_CASE("C API - Query timeout and last data queries", "[c_queryLast]") { - CaseReporter cr("c_queryLast"); - prepareTimeseries(); - - const char* deviceId = "root.ctest.d1"; - const char* measurements[] = {"s1", "s2", "s3"}; - for (int64_t time = 300; time < 310; time++) { - const char* values[] = {"7", "8", "9"}; - REQUIRE(ts_session_insert_record_str(g_session, deviceId, time, 3, measurements, values) == TS_OK); - } - - const char* paths[] = {"root.ctest.d1.s1", "root.ctest.d1.s2"}; - CSessionDataSet* ds = nullptr; - REQUIRE(ts_session_execute_query_with_timeout(g_session, "select s1 from root.ctest.d1 where time>=300", 60000, - &ds) == TS_OK); - REQUIRE(ds != nullptr); - ts_dataset_destroy(ds); - - ds = nullptr; - REQUIRE(ts_session_execute_last_data_query(g_session, 2, paths, &ds) == TS_OK); - REQUIRE(ds != nullptr); - ts_dataset_destroy(ds); - - ds = nullptr; - REQUIRE(ts_session_execute_last_data_query_with_time(g_session, 2, paths, 305LL, &ds) == TS_OK); - REQUIRE(ds != nullptr); - ts_dataset_destroy(ds); + CaseReporter cr("c_queryLast"); + prepareTimeseries(); + + const char* deviceId = "root.ctest.d1"; + const char* measurements[] = {"s1", "s2", "s3"}; + for (int64_t time = 300; time < 310; time++) { + const char* values[] = {"7", "8", "9"}; + REQUIRE(ts_session_insert_record_str(g_session, deviceId, time, 3, measurements, values) == + TS_OK); + } + + const char* paths[] = {"root.ctest.d1.s1", "root.ctest.d1.s2"}; + CSessionDataSet* ds = nullptr; + REQUIRE(ts_session_execute_query_with_timeout( + g_session, "select s1 from root.ctest.d1 where time>=300", 60000, &ds) == TS_OK); + REQUIRE(ds != nullptr); + ts_dataset_destroy(ds); + + ds = nullptr; + REQUIRE(ts_session_execute_last_data_query(g_session, 2, paths, &ds) == TS_OK); + REQUIRE(ds != nullptr); + ts_dataset_destroy(ds); + + ds = nullptr; + REQUIRE(ts_session_execute_last_data_query_with_time(g_session, 2, paths, 305LL, &ds) == TS_OK); + REQUIRE(ds != nullptr); + ts_dataset_destroy(ds); } TEST_CASE("C API - RowRecord and delete data APIs", "[c_rowDelete]") { - CaseReporter cr("c_rowDelete"); - - const char* sg = "root.cov_types"; - dropDatabaseIfExists(g_session, sg); - REQUIRE(ts_session_create_database(g_session, sg) == TS_OK); - - const char* pb = "root.cov_types.d1.sb"; - const char* pi = "root.cov_types.d1.si"; - const char* pf = "root.cov_types.d1.sf"; - const char* pd = "root.cov_types.d1.sd"; - const char* pt = "root.cov_types.d1.st"; - const char* tpaths[] = {pb, pi, pf, pd, pt}; - for (const char* tp : tpaths) { - dropTimeseriesIfExists(g_session, tp); - } - REQUIRE(ts_session_create_timeseries(g_session, pb, TS_TYPE_BOOLEAN, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY) == - TS_OK); - REQUIRE(ts_session_create_timeseries(g_session, pi, TS_TYPE_INT32, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY) == - TS_OK); - REQUIRE(ts_session_create_timeseries(g_session, pf, TS_TYPE_FLOAT, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY) == - TS_OK); - REQUIRE(ts_session_create_timeseries(g_session, pd, TS_TYPE_DOUBLE, TS_ENCODING_RLE, TS_COMPRESSION_SNAPPY) == - TS_OK); - REQUIRE(ts_session_create_timeseries(g_session, pt, TS_TYPE_TEXT, TS_ENCODING_PLAIN, TS_COMPRESSION_SNAPPY) == - TS_OK); - - const char* dev = "root.cov_types.d1"; - const char* names[] = {"sb", "si", "sf", "sd", "st"}; - TSDataType_C types[] = {TS_TYPE_BOOLEAN, TS_TYPE_INT32, TS_TYPE_FLOAT, TS_TYPE_DOUBLE, TS_TYPE_TEXT}; - bool bv = true; - int32_t iv = 42; - float fv = 2.5f; - double dv = 3.25; - const char* tv = "hi"; - const void* vals[] = {&bv, &iv, &fv, &dv, tv}; - REQUIRE(ts_session_insert_record(g_session, dev, 500LL, 5, names, types, vals) == TS_OK); - - CSessionDataSet* dataSet = nullptr; - REQUIRE(ts_session_execute_query( - g_session, "select sb,si,sf,sd,st from root.cov_types.d1 where time=500", &dataSet) == TS_OK); - REQUIRE(dataSet != nullptr); - REQUIRE(ts_dataset_has_next(dataSet)); - CRowRecord* record = ts_dataset_next(dataSet); - REQUIRE(record != nullptr); - REQUIRE(ts_row_record_get_timestamp(record) == 500LL); - REQUIRE(ts_row_record_get_field_count(record) == 5); - REQUIRE_FALSE(ts_row_record_is_null(record, 0)); - REQUIRE(ts_row_record_get_bool(record, 0) == true); - REQUIRE(ts_row_record_get_int32(record, 1) == 42); - REQUIRE(std::fabs(ts_row_record_get_float(record, 2) - 2.5f) < 1e-4f); - REQUIRE(std::fabs(ts_row_record_get_double(record, 3) - 3.25) < 1e-9); - REQUIRE(std::string(ts_row_record_get_string(record, 4)) == "hi"); - REQUIRE(ts_row_record_get_data_type(record, 0) == TS_TYPE_BOOLEAN); - ts_row_record_destroy(record); - ts_dataset_destroy(dataSet); - - REQUIRE(ts_session_delete_data(g_session, pb, 500LL) == TS_OK); - const char* delPaths[] = {pi, pf}; - REQUIRE(ts_session_delete_data_range(g_session, 2, delPaths, 400LL, 600LL) == TS_OK); - - REQUIRE(ts_session_delete_timeseries(g_session, pb) == TS_OK); - REQUIRE(ts_session_delete_timeseries(g_session, pi) == TS_OK); - REQUIRE(ts_session_delete_timeseries(g_session, pf) == TS_OK); - REQUIRE(ts_session_delete_timeseries(g_session, pd) == TS_OK); - REQUIRE(ts_session_delete_timeseries(g_session, pt) == TS_OK); - REQUIRE(ts_session_delete_database(g_session, sg) == TS_OK); + CaseReporter cr("c_rowDelete"); + + const char* sg = "root.cov_types"; + dropDatabaseIfExists(g_session, sg); + REQUIRE(ts_session_create_database(g_session, sg) == TS_OK); + + const char* pb = "root.cov_types.d1.sb"; + const char* pi = "root.cov_types.d1.si"; + const char* pf = "root.cov_types.d1.sf"; + const char* pd = "root.cov_types.d1.sd"; + const char* pt = "root.cov_types.d1.st"; + const char* tpaths[] = {pb, pi, pf, pd, pt}; + for (const char* tp : tpaths) { + dropTimeseriesIfExists(g_session, tp); + } + REQUIRE(ts_session_create_timeseries(g_session, pb, TS_TYPE_BOOLEAN, TS_ENCODING_RLE, + TS_COMPRESSION_SNAPPY) == TS_OK); + REQUIRE(ts_session_create_timeseries(g_session, pi, TS_TYPE_INT32, TS_ENCODING_RLE, + TS_COMPRESSION_SNAPPY) == TS_OK); + REQUIRE(ts_session_create_timeseries(g_session, pf, TS_TYPE_FLOAT, TS_ENCODING_RLE, + TS_COMPRESSION_SNAPPY) == TS_OK); + REQUIRE(ts_session_create_timeseries(g_session, pd, TS_TYPE_DOUBLE, TS_ENCODING_RLE, + TS_COMPRESSION_SNAPPY) == TS_OK); + REQUIRE(ts_session_create_timeseries(g_session, pt, TS_TYPE_TEXT, TS_ENCODING_PLAIN, + TS_COMPRESSION_SNAPPY) == TS_OK); + + const char* dev = "root.cov_types.d1"; + const char* names[] = {"sb", "si", "sf", "sd", "st"}; + TSDataType_C types[] = {TS_TYPE_BOOLEAN, TS_TYPE_INT32, TS_TYPE_FLOAT, TS_TYPE_DOUBLE, + TS_TYPE_TEXT}; + bool bv = true; + int32_t iv = 42; + float fv = 2.5f; + double dv = 3.25; + const char* tv = "hi"; + const void* vals[] = {&bv, &iv, &fv, &dv, tv}; + REQUIRE(ts_session_insert_record(g_session, dev, 500LL, 5, names, types, vals) == TS_OK); + + CSessionDataSet* dataSet = nullptr; + REQUIRE(ts_session_execute_query(g_session, + "select sb,si,sf,sd,st from root.cov_types.d1 where time=500", + &dataSet) == TS_OK); + REQUIRE(dataSet != nullptr); + REQUIRE(ts_dataset_has_next(dataSet)); + CRowRecord* record = ts_dataset_next(dataSet); + REQUIRE(record != nullptr); + REQUIRE(ts_row_record_get_timestamp(record) == 500LL); + REQUIRE(ts_row_record_get_field_count(record) == 5); + REQUIRE_FALSE(ts_row_record_is_null(record, 0)); + REQUIRE(ts_row_record_get_bool(record, 0) == true); + REQUIRE(ts_row_record_get_int32(record, 1) == 42); + REQUIRE(std::fabs(ts_row_record_get_float(record, 2) - 2.5f) < 1e-4f); + REQUIRE(std::fabs(ts_row_record_get_double(record, 3) - 3.25) < 1e-9); + REQUIRE(std::string(ts_row_record_get_string(record, 4)) == "hi"); + REQUIRE(ts_row_record_get_data_type(record, 0) == TS_TYPE_BOOLEAN); + ts_row_record_destroy(record); + ts_dataset_destroy(dataSet); + + REQUIRE(ts_session_delete_data(g_session, pb, 500LL) == TS_OK); + const char* delPaths[] = {pi, pf}; + REQUIRE(ts_session_delete_data_range(g_session, 2, delPaths, 400LL, 600LL) == TS_OK); + + REQUIRE(ts_session_delete_timeseries(g_session, pb) == TS_OK); + REQUIRE(ts_session_delete_timeseries(g_session, pi) == TS_OK); + REQUIRE(ts_session_delete_timeseries(g_session, pf) == TS_OK); + REQUIRE(ts_session_delete_timeseries(g_session, pd) == TS_OK); + REQUIRE(ts_session_delete_timeseries(g_session, pt) == TS_OK); + REQUIRE(ts_session_delete_database(g_session, sg) == TS_OK); } diff --git a/iotdb-client/client-cpp/src/test/cpp/sessionCRelationalIT.cpp b/iotdb-client/client-cpp/src/test/cpp/sessionCRelationalIT.cpp index 4e0a559e706f5..9a78f2512ed44 100644 --- a/iotdb-client/client-cpp/src/test/cpp/sessionCRelationalIT.cpp +++ b/iotdb-client/client-cpp/src/test/cpp/sessionCRelationalIT.cpp @@ -30,16 +30,18 @@ static int global_test_tag = 0; class CaseReporter { public: - CaseReporter(const char* caseNameArg) : caseName(caseNameArg) { - test_tag = global_test_tag++; - std::cout << "C-API Table Test " << test_tag << ": " << caseName << std::endl; - } - ~CaseReporter() { - std::cout << "C-API Table Test " << test_tag << ": " << caseName << " Done" << std::endl << std::endl; - } + CaseReporter(const char* caseNameArg) : caseName(caseNameArg) { + test_tag = global_test_tag++; + std::cout << "C-API Table Test " << test_tag << ": " << caseName << std::endl; + } + ~CaseReporter() { + std::cout << "C-API Table Test " << test_tag << ": " << caseName << " Done" << std::endl + << std::endl; + } + private: - const char* caseName; - int test_tag; + const char* caseName; + int test_tag; }; /* ============================================================ @@ -47,38 +49,38 @@ class CaseReporter { * ============================================================ */ TEST_CASE("C API Table - Create table", "[c_table_createTable][c_table_ddl]") { - CaseReporter cr("c_table_createTable"); - - ts_table_session_execute_non_query(g_table_session, "DROP DATABASE IF EXISTS c_db1"); - TsStatus status = ts_table_session_execute_non_query(g_table_session, "CREATE DATABASE c_db1"); - REQUIRE(status == TS_OK); - - ts_table_session_execute_non_query(g_table_session, "USE \"c_db1\""); - status = ts_table_session_execute_non_query(g_table_session, - "CREATE TABLE c_table0 (" - "tag1 string tag," - "attr1 string attribute," - "m1 double field)"); - REQUIRE(status == TS_OK); - - CSessionDataSet* dataSet = nullptr; - status = ts_table_session_execute_query(g_table_session, "SHOW TABLES", &dataSet); - REQUIRE(status == TS_OK); - REQUIRE(dataSet != nullptr); - - ts_dataset_set_fetch_size(dataSet, 1024); - bool tableExist = false; - while (ts_dataset_has_next(dataSet)) { - CRowRecord* record = ts_dataset_next(dataSet); - const char* tableName = ts_row_record_get_string(record, 0); - if (std::string(tableName) == "c_table0") { - tableExist = true; - } - ts_row_record_destroy(record); - if (tableExist) break; + CaseReporter cr("c_table_createTable"); + + ts_table_session_execute_non_query(g_table_session, "DROP DATABASE IF EXISTS c_db1"); + TsStatus status = ts_table_session_execute_non_query(g_table_session, "CREATE DATABASE c_db1"); + REQUIRE(status == TS_OK); + + ts_table_session_execute_non_query(g_table_session, "USE \"c_db1\""); + status = ts_table_session_execute_non_query(g_table_session, "CREATE TABLE c_table0 (" + "tag1 string tag," + "attr1 string attribute," + "m1 double field)"); + REQUIRE(status == TS_OK); + + CSessionDataSet* dataSet = nullptr; + status = ts_table_session_execute_query(g_table_session, "SHOW TABLES", &dataSet); + REQUIRE(status == TS_OK); + REQUIRE(dataSet != nullptr); + + ts_dataset_set_fetch_size(dataSet, 1024); + bool tableExist = false; + while (ts_dataset_has_next(dataSet)) { + CRowRecord* record = ts_dataset_next(dataSet); + const char* tableName = ts_row_record_get_string(record, 0); + if (std::string(tableName) == "c_table0") { + tableExist = true; } - REQUIRE(tableExist == true); - ts_dataset_destroy(dataSet); + ts_row_record_destroy(record); + if (tableExist) + break; + } + REQUIRE(tableExist == true); + ts_dataset_destroy(dataSet); } /* ============================================================ @@ -86,50 +88,49 @@ TEST_CASE("C API Table - Create table", "[c_table_createTable][c_table_ddl]") { * ============================================================ */ TEST_CASE("C API Table - Insert tablet", "[c_table_insertTablet][c_table_write]") { - CaseReporter cr("c_table_insertTablet"); - - ts_table_session_execute_non_query(g_table_session, "DROP DATABASE IF EXISTS c_db2"); - ts_table_session_execute_non_query(g_table_session, "CREATE DATABASE c_db2"); - ts_table_session_execute_non_query(g_table_session, "USE \"c_db2\""); - ts_table_session_execute_non_query(g_table_session, - "CREATE TABLE c_table1 (" - "tag1 string tag," - "attr1 string attribute," - "m1 double field)"); - - const char* columnNames[] = {"tag1", "attr1", "m1"}; - TSDataType_C dataTypes[] = {TS_TYPE_STRING, TS_TYPE_STRING, TS_TYPE_DOUBLE}; - TSColumnCategory_C colCategories[] = {TS_COL_TAG, TS_COL_ATTRIBUTE, TS_COL_FIELD}; - - CTablet* tablet = ts_tablet_new_with_category("c_table1", 3, columnNames, dataTypes, - colCategories, 100); - REQUIRE(tablet != nullptr); - - for (int i = 0; i < 50; i++) { - ts_tablet_add_timestamp(tablet, i, (int64_t)i); - ts_tablet_add_value_string(tablet, 0, i, "device_A"); - ts_tablet_add_value_string(tablet, 1, i, "attr_val"); - ts_tablet_add_value_double(tablet, 2, i, i * 1.5); - } - ts_tablet_set_row_count(tablet, 50); - - TsStatus status = ts_table_session_insert(g_table_session, tablet); - REQUIRE(status == TS_OK); - - CSessionDataSet* dataSet = nullptr; - status = ts_table_session_execute_query(g_table_session, "SELECT * FROM c_table1", &dataSet); - REQUIRE(status == TS_OK); - - ts_dataset_set_fetch_size(dataSet, 1024); - int count = 0; - while (ts_dataset_has_next(dataSet)) { - CRowRecord* record = ts_dataset_next(dataSet); - count++; - ts_row_record_destroy(record); - } - REQUIRE(count == 50); - ts_dataset_destroy(dataSet); - ts_tablet_destroy(tablet); + CaseReporter cr("c_table_insertTablet"); + + ts_table_session_execute_non_query(g_table_session, "DROP DATABASE IF EXISTS c_db2"); + ts_table_session_execute_non_query(g_table_session, "CREATE DATABASE c_db2"); + ts_table_session_execute_non_query(g_table_session, "USE \"c_db2\""); + ts_table_session_execute_non_query(g_table_session, "CREATE TABLE c_table1 (" + "tag1 string tag," + "attr1 string attribute," + "m1 double field)"); + + const char* columnNames[] = {"tag1", "attr1", "m1"}; + TSDataType_C dataTypes[] = {TS_TYPE_STRING, TS_TYPE_STRING, TS_TYPE_DOUBLE}; + TSColumnCategory_C colCategories[] = {TS_COL_TAG, TS_COL_ATTRIBUTE, TS_COL_FIELD}; + + CTablet* tablet = + ts_tablet_new_with_category("c_table1", 3, columnNames, dataTypes, colCategories, 100); + REQUIRE(tablet != nullptr); + + for (int i = 0; i < 50; i++) { + ts_tablet_add_timestamp(tablet, i, (int64_t)i); + ts_tablet_add_value_string(tablet, 0, i, "device_A"); + ts_tablet_add_value_string(tablet, 1, i, "attr_val"); + ts_tablet_add_value_double(tablet, 2, i, i * 1.5); + } + ts_tablet_set_row_count(tablet, 50); + + TsStatus status = ts_table_session_insert(g_table_session, tablet); + REQUIRE(status == TS_OK); + + CSessionDataSet* dataSet = nullptr; + status = ts_table_session_execute_query(g_table_session, "SELECT * FROM c_table1", &dataSet); + REQUIRE(status == TS_OK); + + ts_dataset_set_fetch_size(dataSet, 1024); + int count = 0; + while (ts_dataset_has_next(dataSet)) { + CRowRecord* record = ts_dataset_next(dataSet); + count++; + ts_row_record_destroy(record); + } + REQUIRE(count == 50); + ts_dataset_destroy(dataSet); + ts_tablet_destroy(tablet); } /* ============================================================ @@ -137,42 +138,42 @@ TEST_CASE("C API Table - Insert tablet", "[c_table_insertTablet][c_table_write]" * ============================================================ */ TEST_CASE("C API Table - Query with timeout", "[c_table_queryTimeout][c_table_query]") { - CaseReporter cr("c_table_queryTimeout"); - - ts_table_session_execute_non_query(g_table_session, "DROP DATABASE IF EXISTS c_db3"); - ts_table_session_execute_non_query(g_table_session, "CREATE DATABASE c_db3"); - ts_table_session_execute_non_query(g_table_session, "USE \"c_db3\""); - ts_table_session_execute_non_query(g_table_session, - "CREATE TABLE c_table2 (tag1 string tag, m1 int32 field)"); - - const char* columnNames[] = {"tag1", "m1"}; - TSDataType_C dataTypes[] = {TS_TYPE_STRING, TS_TYPE_INT32}; - TSColumnCategory_C colCategories[] = {TS_COL_TAG, TS_COL_FIELD}; - - CTablet* tablet = ts_tablet_new_with_category("c_table2", 2, columnNames, dataTypes, - colCategories, 10); - for (int i = 0; i < 10; i++) { - ts_tablet_add_timestamp(tablet, i, (int64_t)i); - ts_tablet_add_value_string(tablet, 0, i, "dev1"); - ts_tablet_add_value_int32(tablet, 1, i, i * 10); - } - ts_tablet_set_row_count(tablet, 10); - ts_table_session_insert(g_table_session, tablet); - ts_tablet_destroy(tablet); - - CSessionDataSet* dataSet = nullptr; - TsStatus status = ts_table_session_execute_query_with_timeout(g_table_session, - "SELECT * FROM c_table2", 60000, &dataSet); - REQUIRE(status == TS_OK); - - int count = 0; - while (ts_dataset_has_next(dataSet)) { - CRowRecord* record = ts_dataset_next(dataSet); - count++; - ts_row_record_destroy(record); - } - REQUIRE(count == 10); - ts_dataset_destroy(dataSet); + CaseReporter cr("c_table_queryTimeout"); + + ts_table_session_execute_non_query(g_table_session, "DROP DATABASE IF EXISTS c_db3"); + ts_table_session_execute_non_query(g_table_session, "CREATE DATABASE c_db3"); + ts_table_session_execute_non_query(g_table_session, "USE \"c_db3\""); + ts_table_session_execute_non_query(g_table_session, + "CREATE TABLE c_table2 (tag1 string tag, m1 int32 field)"); + + const char* columnNames[] = {"tag1", "m1"}; + TSDataType_C dataTypes[] = {TS_TYPE_STRING, TS_TYPE_INT32}; + TSColumnCategory_C colCategories[] = {TS_COL_TAG, TS_COL_FIELD}; + + CTablet* tablet = + ts_tablet_new_with_category("c_table2", 2, columnNames, dataTypes, colCategories, 10); + for (int i = 0; i < 10; i++) { + ts_tablet_add_timestamp(tablet, i, (int64_t)i); + ts_tablet_add_value_string(tablet, 0, i, "dev1"); + ts_tablet_add_value_int32(tablet, 1, i, i * 10); + } + ts_tablet_set_row_count(tablet, 10); + ts_table_session_insert(g_table_session, tablet); + ts_tablet_destroy(tablet); + + CSessionDataSet* dataSet = nullptr; + TsStatus status = ts_table_session_execute_query_with_timeout( + g_table_session, "SELECT * FROM c_table2", 60000, &dataSet); + REQUIRE(status == TS_OK); + + int count = 0; + while (ts_dataset_has_next(dataSet)) { + CRowRecord* record = ts_dataset_next(dataSet); + count++; + ts_row_record_destroy(record); + } + REQUIRE(count == 10); + ts_dataset_destroy(dataSet); } /* ============================================================ @@ -180,57 +181,57 @@ TEST_CASE("C API Table - Query with timeout", "[c_table_queryTimeout][c_table_qu * ============================================================ */ TEST_CASE("C API Table - Multi-type tablet", "[c_table_multiType][c_table_write]") { - CaseReporter cr("c_table_multiType"); - - ts_table_session_execute_non_query(g_table_session, "DROP DATABASE IF EXISTS c_db4"); - ts_table_session_execute_non_query(g_table_session, "CREATE DATABASE c_db4"); - ts_table_session_execute_non_query(g_table_session, "USE \"c_db4\""); - ts_table_session_execute_non_query(g_table_session, - "CREATE TABLE c_table3 (" - "tag1 string tag," - "m_bool boolean field," - "m_int32 int32 field," - "m_int64 int64 field," - "m_float float field," - "m_double double field," - "m_text text field)"); - - const char* columnNames[] = {"tag1", "m_bool", "m_int32", "m_int64", "m_float", "m_double", "m_text"}; - TSDataType_C dataTypes[] = {TS_TYPE_STRING, TS_TYPE_BOOLEAN, TS_TYPE_INT32, TS_TYPE_INT64, - TS_TYPE_FLOAT, TS_TYPE_DOUBLE, TS_TYPE_TEXT}; - TSColumnCategory_C colCategories[] = {TS_COL_TAG, TS_COL_FIELD, TS_COL_FIELD, TS_COL_FIELD, - TS_COL_FIELD, TS_COL_FIELD, TS_COL_FIELD}; - - CTablet* tablet = ts_tablet_new_with_category("c_table3", 7, columnNames, dataTypes, - colCategories, 20); - for (int i = 0; i < 20; i++) { - ts_tablet_add_timestamp(tablet, i, (int64_t)(i + 1000)); - ts_tablet_add_value_string(tablet, 0, i, "dev1"); - ts_tablet_add_value_bool(tablet, 1, i, (i % 2 == 0)); - ts_tablet_add_value_int32(tablet, 2, i, i * 10); - ts_tablet_add_value_int64(tablet, 3, i, (int64_t)i * 100); - ts_tablet_add_value_float(tablet, 4, i, i * 1.1f); - ts_tablet_add_value_double(tablet, 5, i, i * 2.2); - ts_tablet_add_value_string(tablet, 6, i, "hello"); - } - ts_tablet_set_row_count(tablet, 20); - - TsStatus status = ts_table_session_insert(g_table_session, tablet); - REQUIRE(status == TS_OK); - - CSessionDataSet* dataSet = nullptr; - status = ts_table_session_execute_query(g_table_session, "SELECT * FROM c_table3", &dataSet); - REQUIRE(status == TS_OK); - - int count = 0; - while (ts_dataset_has_next(dataSet)) { - CRowRecord* record = ts_dataset_next(dataSet); - count++; - ts_row_record_destroy(record); - } - REQUIRE(count == 20); - ts_dataset_destroy(dataSet); - ts_tablet_destroy(tablet); + CaseReporter cr("c_table_multiType"); + + ts_table_session_execute_non_query(g_table_session, "DROP DATABASE IF EXISTS c_db4"); + ts_table_session_execute_non_query(g_table_session, "CREATE DATABASE c_db4"); + ts_table_session_execute_non_query(g_table_session, "USE \"c_db4\""); + ts_table_session_execute_non_query(g_table_session, "CREATE TABLE c_table3 (" + "tag1 string tag," + "m_bool boolean field," + "m_int32 int32 field," + "m_int64 int64 field," + "m_float float field," + "m_double double field," + "m_text text field)"); + + const char* columnNames[] = {"tag1", "m_bool", "m_int32", "m_int64", + "m_float", "m_double", "m_text"}; + TSDataType_C dataTypes[] = {TS_TYPE_STRING, TS_TYPE_BOOLEAN, TS_TYPE_INT32, TS_TYPE_INT64, + TS_TYPE_FLOAT, TS_TYPE_DOUBLE, TS_TYPE_TEXT}; + TSColumnCategory_C colCategories[] = {TS_COL_TAG, TS_COL_FIELD, TS_COL_FIELD, TS_COL_FIELD, + TS_COL_FIELD, TS_COL_FIELD, TS_COL_FIELD}; + + CTablet* tablet = + ts_tablet_new_with_category("c_table3", 7, columnNames, dataTypes, colCategories, 20); + for (int i = 0; i < 20; i++) { + ts_tablet_add_timestamp(tablet, i, (int64_t)(i + 1000)); + ts_tablet_add_value_string(tablet, 0, i, "dev1"); + ts_tablet_add_value_bool(tablet, 1, i, (i % 2 == 0)); + ts_tablet_add_value_int32(tablet, 2, i, i * 10); + ts_tablet_add_value_int64(tablet, 3, i, (int64_t)i * 100); + ts_tablet_add_value_float(tablet, 4, i, i * 1.1f); + ts_tablet_add_value_double(tablet, 5, i, i * 2.2); + ts_tablet_add_value_string(tablet, 6, i, "hello"); + } + ts_tablet_set_row_count(tablet, 20); + + TsStatus status = ts_table_session_insert(g_table_session, tablet); + REQUIRE(status == TS_OK); + + CSessionDataSet* dataSet = nullptr; + status = ts_table_session_execute_query(g_table_session, "SELECT * FROM c_table3", &dataSet); + REQUIRE(status == TS_OK); + + int count = 0; + while (ts_dataset_has_next(dataSet)) { + CRowRecord* record = ts_dataset_next(dataSet); + count++; + ts_row_record_destroy(record); + } + REQUIRE(count == 20); + ts_dataset_destroy(dataSet); + ts_tablet_destroy(tablet); } /* ============================================================ @@ -238,18 +239,19 @@ TEST_CASE("C API Table - Multi-type tablet", "[c_table_multiType][c_table_write] * ============================================================ */ TEST_CASE("C API Table - Multi-node table session", "[c_table_multiNode][c_table_lifecycle]") { - CaseReporter cr("c_table_multiNode"); + CaseReporter cr("c_table_multiNode"); - const char* urls[] = {"127.0.0.1:6667"}; - CTableSession* localSession = ts_table_session_new_multi_node(urls, 1, "root", "root", ""); - REQUIRE(localSession != nullptr); + const char* urls[] = {"127.0.0.1:6667"}; + CTableSession* localSession = ts_table_session_new_multi_node(urls, 1, "root", "root", ""); + REQUIRE(localSession != nullptr); - TsStatus status = ts_table_session_execute_non_query(localSession, "DROP DATABASE IF EXISTS c_db5"); - REQUIRE(status == TS_OK); - ts_table_session_execute_non_query(localSession, "CREATE DATABASE c_db5"); + TsStatus status = + ts_table_session_execute_non_query(localSession, "DROP DATABASE IF EXISTS c_db5"); + REQUIRE(status == TS_OK); + ts_table_session_execute_non_query(localSession, "CREATE DATABASE c_db5"); - ts_table_session_close(localSession); - ts_table_session_destroy(localSession); + ts_table_session_close(localSession); + ts_table_session_destroy(localSession); } /* ============================================================ @@ -257,51 +259,51 @@ TEST_CASE("C API Table - Multi-node table session", "[c_table_multiNode][c_table * ============================================================ */ TEST_CASE("C API Table - Dataset column info", "[c_table_datasetColumns][c_table_query]") { - CaseReporter cr("c_table_datasetColumns"); - - ts_table_session_execute_non_query(g_table_session, "DROP DATABASE IF EXISTS c_db6"); - ts_table_session_execute_non_query(g_table_session, "CREATE DATABASE c_db6"); - ts_table_session_execute_non_query(g_table_session, "USE \"c_db6\""); - ts_table_session_execute_non_query(g_table_session, - "CREATE TABLE c_table6 (tag1 string tag, m1 int64 field)"); - - const char* columnNames[] = {"tag1", "m1"}; - TSDataType_C dataTypes[] = {TS_TYPE_STRING, TS_TYPE_INT64}; - TSColumnCategory_C colCategories[] = {TS_COL_TAG, TS_COL_FIELD}; - - CTablet* tablet = ts_tablet_new_with_category("c_table6", 2, columnNames, dataTypes, - colCategories, 5); - for (int i = 0; i < 5; i++) { - ts_tablet_add_timestamp(tablet, i, (int64_t)i); - ts_tablet_add_value_string(tablet, 0, i, "dev1"); - ts_tablet_add_value_int64(tablet, 1, i, (int64_t)(i * 100)); - } - ts_tablet_set_row_count(tablet, 5); - ts_table_session_insert(g_table_session, tablet); - ts_tablet_destroy(tablet); - - CSessionDataSet* dataSet = nullptr; - ts_table_session_execute_query(g_table_session, "SELECT * FROM c_table6", &dataSet); - REQUIRE(dataSet != nullptr); - - int colCount = ts_dataset_get_column_count(dataSet); - REQUIRE(colCount >= 2); // at least time + tag1 + m1 - - for (int i = 0; i < colCount; i++) { - const char* colType = ts_dataset_get_column_type(dataSet, i); - REQUIRE(colType != nullptr); - REQUIRE(strlen(colType) > 0); - } - - if (ts_dataset_has_next(dataSet)) { - CRowRecord* record = ts_dataset_next(dataSet); - REQUIRE(record != nullptr); - REQUIRE(ts_row_record_get_field_count(record) >= 1); - (void)ts_row_record_get_timestamp(record); - (void)ts_row_record_get_data_type(record, 0); - (void)ts_row_record_is_null(record, 0); - ts_row_record_destroy(record); - } - - ts_dataset_destroy(dataSet); + CaseReporter cr("c_table_datasetColumns"); + + ts_table_session_execute_non_query(g_table_session, "DROP DATABASE IF EXISTS c_db6"); + ts_table_session_execute_non_query(g_table_session, "CREATE DATABASE c_db6"); + ts_table_session_execute_non_query(g_table_session, "USE \"c_db6\""); + ts_table_session_execute_non_query(g_table_session, + "CREATE TABLE c_table6 (tag1 string tag, m1 int64 field)"); + + const char* columnNames[] = {"tag1", "m1"}; + TSDataType_C dataTypes[] = {TS_TYPE_STRING, TS_TYPE_INT64}; + TSColumnCategory_C colCategories[] = {TS_COL_TAG, TS_COL_FIELD}; + + CTablet* tablet = + ts_tablet_new_with_category("c_table6", 2, columnNames, dataTypes, colCategories, 5); + for (int i = 0; i < 5; i++) { + ts_tablet_add_timestamp(tablet, i, (int64_t)i); + ts_tablet_add_value_string(tablet, 0, i, "dev1"); + ts_tablet_add_value_int64(tablet, 1, i, (int64_t)(i * 100)); + } + ts_tablet_set_row_count(tablet, 5); + ts_table_session_insert(g_table_session, tablet); + ts_tablet_destroy(tablet); + + CSessionDataSet* dataSet = nullptr; + ts_table_session_execute_query(g_table_session, "SELECT * FROM c_table6", &dataSet); + REQUIRE(dataSet != nullptr); + + int colCount = ts_dataset_get_column_count(dataSet); + REQUIRE(colCount >= 2); // at least time + tag1 + m1 + + for (int i = 0; i < colCount; i++) { + const char* colType = ts_dataset_get_column_type(dataSet, i); + REQUIRE(colType != nullptr); + REQUIRE(strlen(colType) > 0); + } + + if (ts_dataset_has_next(dataSet)) { + CRowRecord* record = ts_dataset_next(dataSet); + REQUIRE(record != nullptr); + REQUIRE(ts_row_record_get_field_count(record) >= 1); + (void)ts_row_record_get_timestamp(record); + (void)ts_row_record_get_data_type(record, 0); + (void)ts_row_record_is_null(record, 0); + ts_row_record_destroy(record); + } + + ts_dataset_destroy(dataSet); } diff --git a/iotdb-client/client-cpp/src/test/cpp/sessionIT.cpp b/iotdb-client/client-cpp/src/test/cpp/sessionIT.cpp index c5e6e9060832d..1f9abb153efd9 100644 --- a/iotdb-client/client-cpp/src/test/cpp/sessionIT.cpp +++ b/iotdb-client/client-cpp/src/test/cpp/sessionIT.cpp @@ -29,840 +29,853 @@ extern std::shared_ptr session; static vector testTimeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3"}; void prepareTimeseries() { - for (const string ×eries: testTimeseries) { - if (session->checkTimeseriesExists(timeseries)) { - session->deleteTimeseries(timeseries); - } - session->createTimeseries(timeseries, TSDataType::INT64, TSEncoding::RLE, CompressionType::SNAPPY); + for (const string& timeseries : testTimeseries) { + if (session->checkTimeseriesExists(timeseries)) { + session->deleteTimeseries(timeseries); } + session->createTimeseries(timeseries, TSDataType::INT64, TSEncoding::RLE, + CompressionType::SNAPPY); + } } static int global_test_id = 0; -class CaseReporter -{ +class CaseReporter { public: - CaseReporter(const char *caseNameArg) : caseName(caseNameArg) - { - test_id = global_test_id++; - std::cout << "Test " << test_id << ": " << caseName << std::endl; - } - ~CaseReporter() - { - std::cout << "Test " << test_id << ": " << caseName << " Done"<< std::endl << std::endl; - } + CaseReporter(const char* caseNameArg) : caseName(caseNameArg) { + test_id = global_test_id++; + std::cout << "Test " << test_id << ": " << caseName << std::endl; + } + ~CaseReporter() { + std::cout << "Test " << test_id << ": " << caseName << " Done" << std::endl << std::endl; + } + private: - const char *caseName; - int test_id; + const char* caseName; + int test_id; }; TEST_CASE("Create timeseries success", "[createTimeseries]") { - CaseReporter cr("createTimeseries"); - if (!session->checkTimeseriesExists("root.test.d1.s1")) { - session->createTimeseries("root.test.d1.s1", TSDataType::INT64, TSEncoding::RLE, CompressionType::SNAPPY); - } - REQUIRE(session->checkTimeseriesExists("root.test.d1.s1") == true); - session->deleteTimeseries("root.test.d1.s1"); + CaseReporter cr("createTimeseries"); + if (!session->checkTimeseriesExists("root.test.d1.s1")) { + session->createTimeseries("root.test.d1.s1", TSDataType::INT64, TSEncoding::RLE, + CompressionType::SNAPPY); + } + REQUIRE(session->checkTimeseriesExists("root.test.d1.s1") == true); + session->deleteTimeseries("root.test.d1.s1"); } TEST_CASE("Login Test - Authentication failed with error code 801", "[Authentication]") { - CaseReporter cr("Login Test"); - - try { - Session session("127.0.0.1", 6667, "root", "wrong-password"); - session.open(false); - FAIL("Expected authentication exception"); // Test fails if no exception - } catch (const std::exception& e) { - // Verify exception contains error code 801 - REQUIRE(std::string(e.what()).find("801") != std::string::npos); - } + CaseReporter cr("Login Test"); + + try { + Session session("127.0.0.1", 6667, "root", "wrong-password"); + session.open(false); + FAIL("Expected authentication exception"); // Test fails if no exception + } catch (const std::exception& e) { + // Verify exception contains error code 801 + REQUIRE(std::string(e.what()).find("801") != std::string::npos); + } } TEST_CASE("Test Session constructor with nodeUrls", "[SessionInitAndOperate]") { - CaseReporter cr("SessionInitWithNodeUrls"); - - std::vector nodeUrls = {"127.0.0.1:6667"}; - std::shared_ptr localSession = std::make_shared(nodeUrls, "root", "root"); - localSession->open(); - if (!localSession->checkTimeseriesExists("root.test.d1.s1")) { - localSession->createTimeseries("root.test.d1.s1", TSDataType::INT64, TSEncoding::RLE, CompressionType::SNAPPY); - } - REQUIRE(localSession->checkTimeseriesExists("root.test.d1.s1") == true); - localSession->deleteTimeseries("root.test.d1.s1"); - localSession->close(); + CaseReporter cr("SessionInitWithNodeUrls"); + + std::vector nodeUrls = {"127.0.0.1:6667"}; + std::shared_ptr localSession = std::make_shared(nodeUrls, "root", "root"); + localSession->open(); + if (!localSession->checkTimeseriesExists("root.test.d1.s1")) { + localSession->createTimeseries("root.test.d1.s1", TSDataType::INT64, TSEncoding::RLE, + CompressionType::SNAPPY); + } + REQUIRE(localSession->checkTimeseriesExists("root.test.d1.s1") == true); + localSession->deleteTimeseries("root.test.d1.s1"); + localSession->close(); } TEST_CASE("Test Session builder with nodeUrls", "[SessionBuilderInit]") { - CaseReporter cr("SessionInitWithNodeUrls"); - - std::vector nodeUrls = {"127.0.0.1:6667"}; - auto builder = std::unique_ptr(new SessionBuilder()); - std::shared_ptr session = - std::shared_ptr( - builder - ->username("root") - ->password("root") - ->nodeUrls(nodeUrls) - ->build() - ); - session->open(); - if (!session->checkTimeseriesExists("root.test.d1.s1")) { - session->createTimeseries("root.test.d1.s1", TSDataType::INT64, TSEncoding::RLE, CompressionType::SNAPPY); - } - REQUIRE(session->checkTimeseriesExists("root.test.d1.s1") == true); - session->deleteTimeseries("root.test.d1.s1"); - session->close(); + CaseReporter cr("SessionInitWithNodeUrls"); + + std::vector nodeUrls = {"127.0.0.1:6667"}; + auto builder = std::unique_ptr(new SessionBuilder()); + std::shared_ptr session = std::shared_ptr( + builder->username("root")->password("root")->nodeUrls(nodeUrls)->build()); + session->open(); + if (!session->checkTimeseriesExists("root.test.d1.s1")) { + session->createTimeseries("root.test.d1.s1", TSDataType::INT64, TSEncoding::RLE, + CompressionType::SNAPPY); + } + REQUIRE(session->checkTimeseriesExists("root.test.d1.s1") == true); + session->deleteTimeseries("root.test.d1.s1"); + session->close(); } TEST_CASE("Delete timeseries success", "[deleteTimeseries]") { - CaseReporter cr("deleteTimeseries"); - if (!session->checkTimeseriesExists("root.test.d1.s1")) { - session->createTimeseries("root.test.d1.s1", TSDataType::INT64, TSEncoding::RLE, CompressionType::SNAPPY); - } - REQUIRE(session->checkTimeseriesExists("root.test.d1.s1") == true); - session->deleteTimeseries("root.test.d1.s1"); - REQUIRE(session->checkTimeseriesExists("root.test.d1.s1") == false); + CaseReporter cr("deleteTimeseries"); + if (!session->checkTimeseriesExists("root.test.d1.s1")) { + session->createTimeseries("root.test.d1.s1", TSDataType::INT64, TSEncoding::RLE, + CompressionType::SNAPPY); + } + REQUIRE(session->checkTimeseriesExists("root.test.d1.s1") == true); + session->deleteTimeseries("root.test.d1.s1"); + REQUIRE(session->checkTimeseriesExists("root.test.d1.s1") == false); } TEST_CASE("Test insertRecord by string", "[testInsertRecord]") { - CaseReporter cr("testInsertRecord"); - prepareTimeseries(); - string deviceId = "root.test.d1"; - vector measurements = {"s1", "s2", "s3"}; - - for (long time = 0; time < 100; time++) { - vector values = {"1", "2", "3"}; - session->insertRecord(deviceId, time, measurements, values); - } - - session->executeNonQueryStatement("insert into root.test.d1(timestamp,s1, s2, s3) values(100, 1,2,3)"); - - unique_ptr sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); - sessionDataSet->setFetchSize(1024); - int count = 0; - while (sessionDataSet->hasNext()) { - long index = 1; - count++; - auto fields = sessionDataSet->next()->fields; - for (const Field &f: fields) { - REQUIRE(f.longV.value() == index); - index++; - } - } - REQUIRE(count == 101); + CaseReporter cr("testInsertRecord"); + prepareTimeseries(); + string deviceId = "root.test.d1"; + vector measurements = {"s1", "s2", "s3"}; + + for (long time = 0; time < 100; time++) { + vector values = {"1", "2", "3"}; + session->insertRecord(deviceId, time, measurements, values); + } + + session->executeNonQueryStatement( + "insert into root.test.d1(timestamp,s1, s2, s3) values(100, 1,2,3)"); + + unique_ptr sessionDataSet = + session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); + sessionDataSet->setFetchSize(1024); + int count = 0; + while (sessionDataSet->hasNext()) { + long index = 1; + count++; + auto fields = sessionDataSet->next()->fields; + for (const Field& f : fields) { + REQUIRE(f.longV.value() == index); + index++; + } + } + REQUIRE(count == 101); } TEST_CASE("Test insertRecords ", "[testInsertRecords]") { - CaseReporter cr("testInsertRecords"); - prepareTimeseries(); - string deviceId = "root.test.d1"; - vector measurements = {"s1", "s2", "s3"}; - vector deviceIds; - vector> measurementsList; - vector> valuesList; - vector timestamps; - - int64_t COUNT = 500; - for (int64_t time = 1; time <= COUNT; time++) { - vector values = {"1", "2", "3"}; - - deviceIds.push_back(deviceId); - measurementsList.push_back(measurements); - valuesList.push_back(values); - timestamps.push_back(time); - if (time != 0 && time % 100 == 0) { - session->insertRecords(deviceIds, timestamps, measurementsList, valuesList); - deviceIds.clear(); - measurementsList.clear(); - valuesList.clear(); - timestamps.clear(); - } - } - - if (timestamps.size() > 0) { - session->insertRecords(deviceIds, timestamps, measurementsList, valuesList); - } - - unique_ptr sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); - sessionDataSet->setFetchSize(1024); - int count = 0; - while (sessionDataSet->hasNext()) { - long index = 1; - count++; - auto fields = sessionDataSet->next()->fields; - for (const Field &f: fields) { - REQUIRE(f.longV.value() == index); - index++; - } - } - REQUIRE(count == COUNT); + CaseReporter cr("testInsertRecords"); + prepareTimeseries(); + string deviceId = "root.test.d1"; + vector measurements = {"s1", "s2", "s3"}; + vector deviceIds; + vector> measurementsList; + vector> valuesList; + vector timestamps; + + int64_t COUNT = 500; + for (int64_t time = 1; time <= COUNT; time++) { + vector values = {"1", "2", "3"}; + + deviceIds.push_back(deviceId); + measurementsList.push_back(measurements); + valuesList.push_back(values); + timestamps.push_back(time); + if (time != 0 && time % 100 == 0) { + session->insertRecords(deviceIds, timestamps, measurementsList, valuesList); + deviceIds.clear(); + measurementsList.clear(); + valuesList.clear(); + timestamps.clear(); + } + } + + if (timestamps.size() > 0) { + session->insertRecords(deviceIds, timestamps, measurementsList, valuesList); + } + + unique_ptr sessionDataSet = + session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); + sessionDataSet->setFetchSize(1024); + int count = 0; + while (sessionDataSet->hasNext()) { + long index = 1; + count++; + auto fields = sessionDataSet->next()->fields; + for (const Field& f : fields) { + REQUIRE(f.longV.value() == index); + index++; + } + } + REQUIRE(count == COUNT); } TEST_CASE("Test insertRecord with types ", "[testTypedInsertRecord]") { - CaseReporter cr("testTypedInsertRecord"); - vector timeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3"}; - vector types = {TSDataType::INT32, TSDataType::DOUBLE, TSDataType::INT64}; - - for (size_t i = 0; i < timeseries.size(); i++) { - if (session->checkTimeseriesExists(timeseries[i])) { - session->deleteTimeseries(timeseries[i]); - } - session->createTimeseries(timeseries[i], types[i], TSEncoding::RLE, CompressionType::SNAPPY); - } - string deviceId = "root.test.d1"; - vector measurements = {"s1", "s2", "s3"}; - vector value1(100, 1); - vector value2(100, 2.2); - vector value3(100, 3); - - for (long time = 0; time < 100; time++) { - vector values = {(char *) (&value1[time]), (char *) (&value2[time]), (char *) (&value3[time])}; - session->insertRecord(deviceId, time, measurements, types, values); - } - - unique_ptr sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); - sessionDataSet->setFetchSize(1024); - long count = 0; - while (sessionDataSet->hasNext()) { - sessionDataSet->next(); - count++; - } - REQUIRE(count == 100); + CaseReporter cr("testTypedInsertRecord"); + vector timeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3"}; + vector types = {TSDataType::INT32, TSDataType::DOUBLE, TSDataType::INT64}; + + for (size_t i = 0; i < timeseries.size(); i++) { + if (session->checkTimeseriesExists(timeseries[i])) { + session->deleteTimeseries(timeseries[i]); + } + session->createTimeseries(timeseries[i], types[i], TSEncoding::RLE, CompressionType::SNAPPY); + } + string deviceId = "root.test.d1"; + vector measurements = {"s1", "s2", "s3"}; + vector value1(100, 1); + vector value2(100, 2.2); + vector value3(100, 3); + + for (long time = 0; time < 100; time++) { + vector values = {(char*)(&value1[time]), (char*)(&value2[time]), (char*)(&value3[time])}; + session->insertRecord(deviceId, time, measurements, types, values); + } + + unique_ptr sessionDataSet = + session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); + sessionDataSet->setFetchSize(1024); + long count = 0; + while (sessionDataSet->hasNext()) { + sessionDataSet->next(); + count++; + } + REQUIRE(count == 100); } - TEST_CASE("Test insertRecord with new datatypes ", "[testTypedInsertRecordNewDatatype]") { - CaseReporter cr("testTypedInsertRecordNewDatatype"); - vector timeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3", "root.test.d1.s4"}; - std::vector types = {TSDataType::TIMESTAMP, - TSDataType::DATE, TSDataType::BLOB, TSDataType::STRING}; - - for (size_t i = 0; i < timeseries.size(); i++) { - if (session->checkTimeseriesExists(timeseries[i])) { - session->deleteTimeseries(timeseries[i]); - } - session->createTimeseries(timeseries[i], types[i], TSEncoding::PLAIN, CompressionType::SNAPPY); - } - string deviceId = "root.test.d1"; - vector measurements = {"s1", "s2", "s3", "s4"}; - int64_t value1 = 20250507; - boost::gregorian::date value2 = boost::gregorian::date(2025, 5, 7); - string value3 = "20250507"; - string value4 = "20250507"; - - for (long time = 0; time < 100; time++) { - vector values = {(char *) (&value1), (char *) (&value2), - const_cast(value3.c_str()), const_cast(value4.c_str())}; - session->insertRecord(deviceId, time, measurements, types, values); - } - - unique_ptr sessionDataSet = session->executeQueryStatement("select s1,s2,s3,s4 from root.test.d1"); - sessionDataSet->setFetchSize(1024); - long count = 0; - while (sessionDataSet->hasNext()) { - auto record = sessionDataSet->next(); - REQUIRE(record->fields.size() == 4); - for (int i = 0; i < 4; i++) { - REQUIRE(types[i] == record->fields[i].dataType); - } - REQUIRE(record->fields[0].longV.value() == value1); - REQUIRE(record->fields[1].dateV.value() == value2); - REQUIRE(record->fields[2].stringV.value() == value3); - REQUIRE(record->fields[3].stringV.value() == value4); - count++; - } - REQUIRE(count == 100); + CaseReporter cr("testTypedInsertRecordNewDatatype"); + vector timeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3", + "root.test.d1.s4"}; + std::vector types = {TSDataType::TIMESTAMP, TSDataType::DATE, + TSDataType::BLOB, TSDataType::STRING}; + + for (size_t i = 0; i < timeseries.size(); i++) { + if (session->checkTimeseriesExists(timeseries[i])) { + session->deleteTimeseries(timeseries[i]); + } + session->createTimeseries(timeseries[i], types[i], TSEncoding::PLAIN, CompressionType::SNAPPY); + } + string deviceId = "root.test.d1"; + vector measurements = {"s1", "s2", "s3", "s4"}; + int64_t value1 = 20250507; + boost::gregorian::date value2 = boost::gregorian::date(2025, 5, 7); + string value3 = "20250507"; + string value4 = "20250507"; + + for (long time = 0; time < 100; time++) { + vector values = {(char*)(&value1), (char*)(&value2), const_cast(value3.c_str()), + const_cast(value4.c_str())}; + session->insertRecord(deviceId, time, measurements, types, values); + } + + unique_ptr sessionDataSet = + session->executeQueryStatement("select s1,s2,s3,s4 from root.test.d1"); + sessionDataSet->setFetchSize(1024); + long count = 0; + while (sessionDataSet->hasNext()) { + auto record = sessionDataSet->next(); + REQUIRE(record->fields.size() == 4); + for (int i = 0; i < 4; i++) { + REQUIRE(types[i] == record->fields[i].dataType); + } + REQUIRE(record->fields[0].longV.value() == value1); + REQUIRE(record->fields[1].dateV.value() == value2); + REQUIRE(record->fields[2].stringV.value() == value3); + REQUIRE(record->fields[3].stringV.value() == value4); + count++; + } + REQUIRE(count == 100); } TEST_CASE("Test insertRecords with types ", "[testTypedInsertRecords]") { - CaseReporter cr("testTypedInsertRecords"); - vector timeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3"}; - vector types = {TSDataType::INT32, TSDataType::DOUBLE, TSDataType::INT64}; - - for (size_t i = 0; i < timeseries.size(); i++) { - if (session->checkTimeseriesExists(timeseries[i])) { - session->deleteTimeseries(timeseries[i]); - } - session->createTimeseries(timeseries[i], types[i], TSEncoding::RLE, CompressionType::SNAPPY); - } - string deviceId = "root.test.d1"; - vector measurements = {"s1", "s2", "s3"}; - vector deviceIds; - vector> measurementsList; - vector> typesList; - vector> valuesList; - vector timestamps; - vector value1(100, 1); - vector value2(100, 2.2); - vector value3(100, 3); - - for (int64_t time = 0; time < 100; time++) { - vector values = {(char *) (&value1[time]), (char *) (&value2[time]), (char *) (&value3[time])}; - deviceIds.push_back(deviceId); - measurementsList.push_back(measurements); - typesList.push_back(types); - valuesList.push_back(values); - timestamps.push_back(time); - } - - session->insertRecords(deviceIds, timestamps, measurementsList, typesList, valuesList); - - unique_ptr sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); - sessionDataSet->setFetchSize(1024); - int count = 0; - while (sessionDataSet->hasNext()) { - sessionDataSet->next(); - count++; - } - REQUIRE(count == 100); + CaseReporter cr("testTypedInsertRecords"); + vector timeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3"}; + vector types = {TSDataType::INT32, TSDataType::DOUBLE, TSDataType::INT64}; + + for (size_t i = 0; i < timeseries.size(); i++) { + if (session->checkTimeseriesExists(timeseries[i])) { + session->deleteTimeseries(timeseries[i]); + } + session->createTimeseries(timeseries[i], types[i], TSEncoding::RLE, CompressionType::SNAPPY); + } + string deviceId = "root.test.d1"; + vector measurements = {"s1", "s2", "s3"}; + vector deviceIds; + vector> measurementsList; + vector> typesList; + vector> valuesList; + vector timestamps; + vector value1(100, 1); + vector value2(100, 2.2); + vector value3(100, 3); + + for (int64_t time = 0; time < 100; time++) { + vector values = {(char*)(&value1[time]), (char*)(&value2[time]), (char*)(&value3[time])}; + deviceIds.push_back(deviceId); + measurementsList.push_back(measurements); + typesList.push_back(types); + valuesList.push_back(values); + timestamps.push_back(time); + } + + session->insertRecords(deviceIds, timestamps, measurementsList, typesList, valuesList); + + unique_ptr sessionDataSet = + session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); + sessionDataSet->setFetchSize(1024); + int count = 0; + while (sessionDataSet->hasNext()) { + sessionDataSet->next(); + count++; + } + REQUIRE(count == 100); } TEST_CASE("Test insertRecordsOfOneDevice", "[testInsertRecordsOfOneDevice]") { - CaseReporter cr("testInsertRecordsOfOneDevice"); - vector timeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3"}; - vector types = {TSDataType::INT32, TSDataType::DOUBLE, TSDataType::INT64}; - - for (size_t i = 0; i < timeseries.size(); i++) { - if (session->checkTimeseriesExists(timeseries[i])) { - session->deleteTimeseries(timeseries[i]); - } - session->createTimeseries(timeseries[i], types[i], TSEncoding::RLE, CompressionType::SNAPPY); - } - string deviceId = "root.test.d1"; - vector measurements = {"s1", "s2", "s3"}; - vector> measurementsList; - vector> typesList; - vector> valuesList; - vector timestamps; - vector value1(100, 1); - vector value2(100, 2.2); - vector value3(100, 3); - - for (int64_t time = 0; time < 100; time++) { - vector values = {(char *) (&value1[time]), (char *) (&value2[time]), (char *) (&value3[time])}; - measurementsList.push_back(measurements); - typesList.push_back(types); - valuesList.push_back(values); - timestamps.push_back(time); - } - - session->insertRecordsOfOneDevice(deviceId, timestamps, measurementsList, typesList, valuesList); - - unique_ptr sessionDataSet = session->executeQueryStatement("select * from root.test.d1"); - sessionDataSet->setFetchSize(1024); - int count = 0; - while (sessionDataSet->hasNext()) { - sessionDataSet->next(); - count++; - } - REQUIRE(count == 100); + CaseReporter cr("testInsertRecordsOfOneDevice"); + vector timeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3"}; + vector types = {TSDataType::INT32, TSDataType::DOUBLE, TSDataType::INT64}; + + for (size_t i = 0; i < timeseries.size(); i++) { + if (session->checkTimeseriesExists(timeseries[i])) { + session->deleteTimeseries(timeseries[i]); + } + session->createTimeseries(timeseries[i], types[i], TSEncoding::RLE, CompressionType::SNAPPY); + } + string deviceId = "root.test.d1"; + vector measurements = {"s1", "s2", "s3"}; + vector> measurementsList; + vector> typesList; + vector> valuesList; + vector timestamps; + vector value1(100, 1); + vector value2(100, 2.2); + vector value3(100, 3); + + for (int64_t time = 0; time < 100; time++) { + vector values = {(char*)(&value1[time]), (char*)(&value2[time]), (char*)(&value3[time])}; + measurementsList.push_back(measurements); + typesList.push_back(types); + valuesList.push_back(values); + timestamps.push_back(time); + } + + session->insertRecordsOfOneDevice(deviceId, timestamps, measurementsList, typesList, valuesList); + + unique_ptr sessionDataSet = + session->executeQueryStatement("select * from root.test.d1"); + sessionDataSet->setFetchSize(1024); + int count = 0; + while (sessionDataSet->hasNext()) { + sessionDataSet->next(); + count++; + } + REQUIRE(count == 100); } TEST_CASE("Test insertTablet ", "[testInsertTablet]") { - CaseReporter cr("testInsertTablet"); - prepareTimeseries(); - string deviceId = "root.test.d1"; - vector> schemaList; - schemaList.emplace_back("s1", TSDataType::INT64); - schemaList.emplace_back("s2", TSDataType::INT64); - schemaList.emplace_back("s3", TSDataType::INT64); - - Tablet tablet(deviceId, schemaList, 100); - for (int64_t time = 0; time < 100; time++) { - int row = tablet.rowSize++; - tablet.timestamps[row] = time; - for (int64_t i = 0; i < 3; i++) { - tablet.addValue(i, row, i); - } - if (tablet.rowSize == tablet.maxRowNumber) { - session->insertTablet(tablet); - tablet.reset(); - } - } - - if (tablet.rowSize != 0) { - session->insertTablet(tablet); - tablet.reset(); - } - unique_ptr sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); - sessionDataSet->setFetchSize(1024); - int count = 0; - while (sessionDataSet->hasNext()) { - long index = 0; - count++; - auto fields = sessionDataSet->next()->fields; - for (const Field &f: fields) { - REQUIRE(f.longV.value() == index); - index++; - } - } - REQUIRE(count == 100); + CaseReporter cr("testInsertTablet"); + prepareTimeseries(); + string deviceId = "root.test.d1"; + vector> schemaList; + schemaList.emplace_back("s1", TSDataType::INT64); + schemaList.emplace_back("s2", TSDataType::INT64); + schemaList.emplace_back("s3", TSDataType::INT64); + + Tablet tablet(deviceId, schemaList, 100); + for (int64_t time = 0; time < 100; time++) { + int row = tablet.rowSize++; + tablet.timestamps[row] = time; + for (int64_t i = 0; i < 3; i++) { + tablet.addValue(i, row, i); + } + if (tablet.rowSize == tablet.maxRowNumber) { + session->insertTablet(tablet); + tablet.reset(); + } + } + + if (tablet.rowSize != 0) { + session->insertTablet(tablet); + tablet.reset(); + } + unique_ptr sessionDataSet = + session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); + sessionDataSet->setFetchSize(1024); + int count = 0; + while (sessionDataSet->hasNext()) { + long index = 0; + count++; + auto fields = sessionDataSet->next()->fields; + for (const Field& f : fields) { + REQUIRE(f.longV.value() == index); + index++; + } + } + REQUIRE(count == 100); } TEST_CASE("Test insertTablets ", "[testInsertTablets]") { - CaseReporter cr("testInsertTablets"); - vector testTimeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3", - "root.test.d2.s1", "root.test.d2.s2", "root.test.d2.s3"}; - for (const string ×eries: testTimeseries) { - if (session->checkTimeseriesExists(timeseries)) { - session->deleteTimeseries(timeseries); - } - session->createTimeseries(timeseries, TSDataType::INT64, TSEncoding::RLE, CompressionType::SNAPPY); - } - vector> schemaList; - schemaList.emplace_back("s1", TSDataType::INT64); - schemaList.emplace_back("s2", TSDataType::INT64); - schemaList.emplace_back("s3", TSDataType::INT64); - - int maxRowNumber = 100; - vector deviceIds = {"root.test.d1", "root.test.d2"}; - vector tablets; - for (const auto& deviceId: deviceIds) { - tablets.emplace_back(deviceId, schemaList, maxRowNumber); - } - for (auto& tablet : tablets) { - for (int64_t time = 0; time < maxRowNumber; time++) { - int row = tablet.rowSize++; - tablet.timestamps[row] = time; - for (int64_t i = 0; i < 3; i++) { - tablet.addValue(i, row, i); - } - } - } - unordered_map tabletsMap; - for (auto& tablet : tablets) { - tabletsMap[tablet.deviceId] = &tablet; - } - session->insertTablets(tabletsMap); - - unique_ptr sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d2"); - sessionDataSet->setFetchSize(1024); - int count = 0; - while (sessionDataSet->hasNext()) { - long index = 0; - count++; - auto fields = sessionDataSet->next()->fields; - for (const Field &f: fields) { - REQUIRE(f.longV.value() == index); - index++; - } - } - REQUIRE(count == 100); + CaseReporter cr("testInsertTablets"); + vector testTimeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3", + "root.test.d2.s1", "root.test.d2.s2", "root.test.d2.s3"}; + for (const string& timeseries : testTimeseries) { + if (session->checkTimeseriesExists(timeseries)) { + session->deleteTimeseries(timeseries); + } + session->createTimeseries(timeseries, TSDataType::INT64, TSEncoding::RLE, + CompressionType::SNAPPY); + } + vector> schemaList; + schemaList.emplace_back("s1", TSDataType::INT64); + schemaList.emplace_back("s2", TSDataType::INT64); + schemaList.emplace_back("s3", TSDataType::INT64); + + int maxRowNumber = 100; + vector deviceIds = {"root.test.d1", "root.test.d2"}; + vector tablets; + for (const auto& deviceId : deviceIds) { + tablets.emplace_back(deviceId, schemaList, maxRowNumber); + } + for (auto& tablet : tablets) { + for (int64_t time = 0; time < maxRowNumber; time++) { + int row = tablet.rowSize++; + tablet.timestamps[row] = time; + for (int64_t i = 0; i < 3; i++) { + tablet.addValue(i, row, i); + } + } + } + unordered_map tabletsMap; + for (auto& tablet : tablets) { + tabletsMap[tablet.deviceId] = &tablet; + } + session->insertTablets(tabletsMap); + + unique_ptr sessionDataSet = + session->executeQueryStatement("select s1,s2,s3 from root.test.d2"); + sessionDataSet->setFetchSize(1024); + int count = 0; + while (sessionDataSet->hasNext()) { + long index = 0; + count++; + auto fields = sessionDataSet->next()->fields; + for (const Field& f : fields) { + REQUIRE(f.longV.value() == index); + index++; + } + } + REQUIRE(count == 100); } TEST_CASE("Test insertTablet multi datatype", "[testInsertTabletMultiDatatype]") { - CaseReporter cr("testInsertTabletNewDatatype"); - string deviceId = "root.test.d2"; - vector> schemaList; - std::vector measurements = {"s1", "s2", "s3", "s4"}; - std::vector dataTypes = {TSDataType::TIMESTAMP, - TSDataType::DATE, TSDataType::BLOB, TSDataType::STRING}; - for (int i = 0; i < 4; i++) { - schemaList.emplace_back(measurements[i], dataTypes[i]); - } - - for (int i = 0; i < 4; i++) { - auto timeseries = deviceId + "." + measurements[i]; - if (session->checkTimeseriesExists(timeseries)) { - session->deleteTimeseries(timeseries); - } - session->createTimeseries(timeseries, dataTypes[i], TSEncoding::PLAIN, CompressionType::UNCOMPRESSED); - } - - int64_t s1Value = 20250507; - boost::gregorian::date s2Value(2025, 5, 7); - std::string s3Value("20250507"); - std::string s4Value("20250507"); - - Tablet tablet(deviceId, schemaList, 100); - for (int64_t time = 0; time < 100; time++) { - int row = tablet.rowSize++; - tablet.timestamps[row] = time; - tablet.addValue(0, row, s1Value); - tablet.addValue(1, row, s2Value); - tablet.addValue(2, row, s3Value); - tablet.addValue(3, row, s4Value); - if (tablet.rowSize == tablet.maxRowNumber) { - session->insertTablet(tablet); - tablet.reset(); - } - } - - if (tablet.rowSize != 0) { - session->insertTablet(tablet); - tablet.reset(); - } - unique_ptr sessionDataSet = session->executeQueryStatement("select s1,s2,s3,s4 from root.test.d2"); - auto dataIter = sessionDataSet->getIterator(); - sessionDataSet->setFetchSize(1024); - int count = 0; - while (dataIter.next()) { - REQUIRE(dataIter.getLongByIndex(2).value() == s1Value); - REQUIRE(dataIter.getDateByIndex(3).value() == s2Value); - REQUIRE(dataIter.getStringByIndex(4).value() == s3Value); - REQUIRE(dataIter.getStringByIndex(5).value() == s4Value); - count++; - } - REQUIRE(count == 100); + CaseReporter cr("testInsertTabletNewDatatype"); + string deviceId = "root.test.d2"; + vector> schemaList; + std::vector measurements = {"s1", "s2", "s3", "s4"}; + std::vector dataTypes = {TSDataType::TIMESTAMP, TSDataType::DATE, + TSDataType::BLOB, TSDataType::STRING}; + for (int i = 0; i < 4; i++) { + schemaList.emplace_back(measurements[i], dataTypes[i]); + } + + for (int i = 0; i < 4; i++) { + auto timeseries = deviceId + "." + measurements[i]; + if (session->checkTimeseriesExists(timeseries)) { + session->deleteTimeseries(timeseries); + } + session->createTimeseries(timeseries, dataTypes[i], TSEncoding::PLAIN, + CompressionType::UNCOMPRESSED); + } + + int64_t s1Value = 20250507; + boost::gregorian::date s2Value(2025, 5, 7); + std::string s3Value("20250507"); + std::string s4Value("20250507"); + + Tablet tablet(deviceId, schemaList, 100); + for (int64_t time = 0; time < 100; time++) { + int row = tablet.rowSize++; + tablet.timestamps[row] = time; + tablet.addValue(0, row, s1Value); + tablet.addValue(1, row, s2Value); + tablet.addValue(2, row, s3Value); + tablet.addValue(3, row, s4Value); + if (tablet.rowSize == tablet.maxRowNumber) { + session->insertTablet(tablet); + tablet.reset(); + } + } + + if (tablet.rowSize != 0) { + session->insertTablet(tablet); + tablet.reset(); + } + unique_ptr sessionDataSet = + session->executeQueryStatement("select s1,s2,s3,s4 from root.test.d2"); + auto dataIter = sessionDataSet->getIterator(); + sessionDataSet->setFetchSize(1024); + int count = 0; + while (dataIter.next()) { + REQUIRE(dataIter.getLongByIndex(2).value() == s1Value); + REQUIRE(dataIter.getDateByIndex(3).value() == s2Value); + REQUIRE(dataIter.getStringByIndex(4).value() == s3Value); + REQUIRE(dataIter.getStringByIndex(5).value() == s4Value); + count++; + } + REQUIRE(count == 100); } TEST_CASE("Test boolean column via DataIterator", "[testBooleanColumnDataIterator]") { - CaseReporter cr("testBooleanColumnDataIterator"); - string deviceId = "root.test.d1"; - string timeseries = "root.test.d1.s1"; + CaseReporter cr("testBooleanColumnDataIterator"); + string deviceId = "root.test.d1"; + string timeseries = "root.test.d1.s1"; - if (session->checkTimeseriesExists(timeseries)) { - session->deleteTimeseries(timeseries); - } - session->createTimeseries(timeseries, TSDataType::BOOLEAN, TSEncoding::PLAIN, CompressionType::SNAPPY); - - // Insert boolean values: even timestamps get true, odd get false - vector measurements = {"s1"}; - vector types = {TSDataType::BOOLEAN}; - for (int64_t time = 0; time < 10; time++) { - bool val = (time % 2 == 0); - vector values = {(char*)&val}; - session->insertRecord(deviceId, time, measurements, types, values); - } - - unique_ptr sessionDataSet = session->executeQueryStatement("select s1 from root.test.d1"); - auto dataIter = sessionDataSet->getIterator(); - sessionDataSet->setFetchSize(1024); - int count = 0; - while (dataIter.next()) { - bool expected = (count % 2 == 0); - // Column 1 is Time, column 2 is s1 - REQUIRE(dataIter.getBooleanByIndex(2).value() == expected); - // Accessing time column (index 1) as boolean should throw - REQUIRE_THROWS_AS(dataIter.getBooleanByIndex(1), IoTDBException); - count++; - } - REQUIRE(count == 10); + if (session->checkTimeseriesExists(timeseries)) { session->deleteTimeseries(timeseries); + } + session->createTimeseries(timeseries, TSDataType::BOOLEAN, TSEncoding::PLAIN, + CompressionType::SNAPPY); + + // Insert boolean values: even timestamps get true, odd get false + vector measurements = {"s1"}; + vector types = {TSDataType::BOOLEAN}; + for (int64_t time = 0; time < 10; time++) { + bool val = (time % 2 == 0); + vector values = {(char*)&val}; + session->insertRecord(deviceId, time, measurements, types, values); + } + + unique_ptr sessionDataSet = + session->executeQueryStatement("select s1 from root.test.d1"); + auto dataIter = sessionDataSet->getIterator(); + sessionDataSet->setFetchSize(1024); + int count = 0; + while (dataIter.next()) { + bool expected = (count % 2 == 0); + // Column 1 is Time, column 2 is s1 + REQUIRE(dataIter.getBooleanByIndex(2).value() == expected); + // Accessing time column (index 1) as boolean should throw + REQUIRE_THROWS_AS(dataIter.getBooleanByIndex(1), IoTDBException); + count++; + } + REQUIRE(count == 10); + session->deleteTimeseries(timeseries); } TEST_CASE("Test Last query ", "[testLastQuery]") { - CaseReporter cr("testLastQuery"); - prepareTimeseries(); - string deviceId = "root.test.d1"; - vector measurements = {"s1", "s2", "s3"}; - - for (long time = 0; time < 100; time++) { - vector values = {"1", "2", "3"}; - session->insertRecord(deviceId, time, measurements, values); - } - - vector measurementValues = {"1", "2", "3"}; - unique_ptr sessionDataSet = session->executeQueryStatement( - "select last s1,s2,s3 from root.test.d1"); - sessionDataSet->setFetchSize(1024); - long index = 0; - while (sessionDataSet->hasNext()) { - vector fields = sessionDataSet->next()->fields; - REQUIRE("1" <= fields[1].stringV.value()); - REQUIRE(fields[1].stringV.value() <= "3"); - index++; - } + CaseReporter cr("testLastQuery"); + prepareTimeseries(); + string deviceId = "root.test.d1"; + vector measurements = {"s1", "s2", "s3"}; + + for (long time = 0; time < 100; time++) { + vector values = {"1", "2", "3"}; + session->insertRecord(deviceId, time, measurements, values); + } + + vector measurementValues = {"1", "2", "3"}; + unique_ptr sessionDataSet = + session->executeQueryStatement("select last s1,s2,s3 from root.test.d1"); + sessionDataSet->setFetchSize(1024); + long index = 0; + while (sessionDataSet->hasNext()) { + vector fields = sessionDataSet->next()->fields; + REQUIRE("1" <= fields[1].stringV.value()); + REQUIRE(fields[1].stringV.value() <= "3"); + index++; + } } TEST_CASE("Test Huge query ", "[testHugeQuery]") { - CaseReporter cr("testHugeQuery"); - prepareTimeseries(); - string deviceId = "root.test.d1"; - vector measurements = {"s1", "s2", "s3"}; - vector types = {TSDataType::INT64, TSDataType::INT64, TSDataType::INT64}; - int64_t value1 = 1, value2 = 2, value3 = 3; - vector values = {(char*)&value1, (char*)&value2, (char*)&value3}; - - long total_count = 500000; - int print_count = 0; - std::cout.width(7); - std::cout << "inserting " << total_count << " rows:" << std::endl; - for (long time = 0; time < total_count; time++) { - session->insertRecord(deviceId, time, measurements, types, values); - if (time != 0 && time % 1000 == 0) { - std::cout << time << "\t" << std::flush; - if (++print_count % 20 == 0) { - std::cout << std::endl; - } - } - } - - unique_ptr sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); - sessionDataSet->setFetchSize(1024); - int count = 0; - print_count = 0; - std::cout << "\n\niterating " << total_count << " rows:" << std::endl; - while (sessionDataSet->hasNext()) { - auto rowRecord = sessionDataSet->next(); - REQUIRE(rowRecord->timestamp == count); - REQUIRE(rowRecord->fields[0].longV.value() == 1); - REQUIRE(rowRecord->fields[1].longV.value() == 2); - REQUIRE(rowRecord->fields[2].longV.value() == 3); - count++; - if (count % 1000 == 0) { - std::cout << count << "\t" << std::flush; - if (++print_count % 20 == 0) { - std::cout << std::endl; - } - } - } - - REQUIRE(count == total_count); + CaseReporter cr("testHugeQuery"); + prepareTimeseries(); + string deviceId = "root.test.d1"; + vector measurements = {"s1", "s2", "s3"}; + vector types = {TSDataType::INT64, TSDataType::INT64, TSDataType::INT64}; + int64_t value1 = 1, value2 = 2, value3 = 3; + vector values = {(char*)&value1, (char*)&value2, (char*)&value3}; + + long total_count = 500000; + int print_count = 0; + std::cout.width(7); + std::cout << "inserting " << total_count << " rows:" << std::endl; + for (long time = 0; time < total_count; time++) { + session->insertRecord(deviceId, time, measurements, types, values); + if (time != 0 && time % 1000 == 0) { + std::cout << time << "\t" << std::flush; + if (++print_count % 20 == 0) { + std::cout << std::endl; + } + } + } + + unique_ptr sessionDataSet = + session->executeQueryStatement("select s1,s2,s3 from root.test.d1"); + sessionDataSet->setFetchSize(1024); + int count = 0; + print_count = 0; + std::cout << "\n\niterating " << total_count << " rows:" << std::endl; + while (sessionDataSet->hasNext()) { + auto rowRecord = sessionDataSet->next(); + REQUIRE(rowRecord->timestamp == count); + REQUIRE(rowRecord->fields[0].longV.value() == 1); + REQUIRE(rowRecord->fields[1].longV.value() == 2); + REQUIRE(rowRecord->fields[2].longV.value() == 3); + count++; + if (count % 1000 == 0) { + std::cout << count << "\t" << std::flush; + if (++print_count % 20 == 0) { + std::cout << std::endl; + } + } + } + + REQUIRE(count == total_count); } - TEST_CASE("Test executeRawDataQuery ", "[executeRawDataQuery]") { - CaseReporter cr("executeRawDataQuery"); - prepareTimeseries(); - - string deviceId = "root.test.d1"; - vector measurements = {"s1", "s2", "s3"}; - vector types = {TSDataType::INT64, TSDataType::INT64, TSDataType::INT64}; - - long total_count = 5000; - vector values; - int64_t valueArray[3]; - for (long time = -total_count; time < total_count; time++) { - valueArray[0] = time; - valueArray[1] = time * 2; - valueArray[2] = time * 3; - values.clear(); - values.push_back((char*)&valueArray[0]); - values.push_back((char*)&valueArray[1]); - values.push_back((char*)&valueArray[2]); - session->insertRecord(deviceId, time, measurements, types, values); - if (time == 100) { //insert 1 big timestamp data for generate un-seq data. - valueArray[0] = 9; - valueArray[2] = 999; - values.clear(); - values.push_back((char*)&valueArray[0]); - values.push_back((char*)&valueArray[2]); - vector measurements2 = {"s1", "s3"}; - vector types2 = {TSDataType::INT64, TSDataType::INT64}; - session->insertRecord(deviceId, 99999, measurements2, types2, values); - } - } - - vector paths; - paths.push_back("root.test.d1.s1"); - paths.push_back("root.test.d1.s2"); - paths.push_back("root.test.d1.s3"); - - //== Test executeRawDataQuery() with negative timestamp - int startTs = -total_count, endTs = total_count; - unique_ptr sessionDataSet = session->executeRawDataQuery(paths, startTs, endTs); - sessionDataSet->setFetchSize(10); - vector columns = sessionDataSet->getColumnNames(); - columns = sessionDataSet->getColumnNames(); - REQUIRE(columns[0] == "Time"); - REQUIRE(columns[1] == paths[0]); - REQUIRE(columns[2] == paths[1]); - REQUIRE(columns[3] == paths[2]); - - int ts = startTs; - while (sessionDataSet->hasNext()) { - auto rowRecordPtr = sessionDataSet->next(); - //cout << rowRecordPtr->toString(); - - vector fields = rowRecordPtr->fields; - REQUIRE(rowRecordPtr->timestamp == ts); - REQUIRE(fields[0].dataType == TSDataType::INT64); - REQUIRE(fields[0].longV.value() == ts); - REQUIRE(fields[1].dataType == TSDataType::INT64); - REQUIRE(fields[1].longV.value() == ts * 2); - REQUIRE(fields[2].dataType == TSDataType::INT64); - REQUIRE(fields[2].longV.value() == ts *3); - ts++; - } - - - //== Test executeRawDataQuery() with null field - startTs = 99999; - endTs = 99999 + 10; - sessionDataSet = session->executeRawDataQuery(paths, startTs, endTs); - - sessionDataSet->setFetchSize(10); - columns = sessionDataSet->getColumnNames(); - for (const string &column : columns) { - cout << column << " " ; - } - cout << endl; - REQUIRE(columns[0] == "Time"); - REQUIRE(columns[1] == paths[0]); - REQUIRE(columns[2] == paths[1]); - REQUIRE(columns[3] == paths[2]); - ts = startTs; - while (sessionDataSet->hasNext()) { - auto rowRecordPtr = sessionDataSet->next(); - cout << rowRecordPtr->toString(); - - vector fields = rowRecordPtr->fields; - REQUIRE(rowRecordPtr->timestamp == ts); - REQUIRE(fields[0].dataType == TSDataType::INT64); - REQUIRE(fields[0].longV.value() == 9); - REQUIRE(fields[1].dataType == TSDataType::UNKNOWN); - REQUIRE(fields[2].dataType == TSDataType::INT64); - REQUIRE(fields[2].longV.value() == 999); - } - - //== Test executeRawDataQuery() with empty data - sessionDataSet = session->executeRawDataQuery(paths, 100000, 110000); - sessionDataSet->setFetchSize(1); - REQUIRE(sessionDataSet->hasNext() == false); + CaseReporter cr("executeRawDataQuery"); + prepareTimeseries(); + + string deviceId = "root.test.d1"; + vector measurements = {"s1", "s2", "s3"}; + vector types = {TSDataType::INT64, TSDataType::INT64, TSDataType::INT64}; + + long total_count = 5000; + vector values; + int64_t valueArray[3]; + for (long time = -total_count; time < total_count; time++) { + valueArray[0] = time; + valueArray[1] = time * 2; + valueArray[2] = time * 3; + values.clear(); + values.push_back((char*)&valueArray[0]); + values.push_back((char*)&valueArray[1]); + values.push_back((char*)&valueArray[2]); + session->insertRecord(deviceId, time, measurements, types, values); + if (time == 100) { //insert 1 big timestamp data for generate un-seq data. + valueArray[0] = 9; + valueArray[2] = 999; + values.clear(); + values.push_back((char*)&valueArray[0]); + values.push_back((char*)&valueArray[2]); + vector measurements2 = {"s1", "s3"}; + vector types2 = {TSDataType::INT64, TSDataType::INT64}; + session->insertRecord(deviceId, 99999, measurements2, types2, values); + } + } + + vector paths; + paths.push_back("root.test.d1.s1"); + paths.push_back("root.test.d1.s2"); + paths.push_back("root.test.d1.s3"); + + //== Test executeRawDataQuery() with negative timestamp + int startTs = -total_count, endTs = total_count; + unique_ptr sessionDataSet = session->executeRawDataQuery(paths, startTs, endTs); + sessionDataSet->setFetchSize(10); + vector columns = sessionDataSet->getColumnNames(); + columns = sessionDataSet->getColumnNames(); + REQUIRE(columns[0] == "Time"); + REQUIRE(columns[1] == paths[0]); + REQUIRE(columns[2] == paths[1]); + REQUIRE(columns[3] == paths[2]); + + int ts = startTs; + while (sessionDataSet->hasNext()) { + auto rowRecordPtr = sessionDataSet->next(); + //cout << rowRecordPtr->toString(); + + vector fields = rowRecordPtr->fields; + REQUIRE(rowRecordPtr->timestamp == ts); + REQUIRE(fields[0].dataType == TSDataType::INT64); + REQUIRE(fields[0].longV.value() == ts); + REQUIRE(fields[1].dataType == TSDataType::INT64); + REQUIRE(fields[1].longV.value() == ts * 2); + REQUIRE(fields[2].dataType == TSDataType::INT64); + REQUIRE(fields[2].longV.value() == ts * 3); + ts++; + } + + //== Test executeRawDataQuery() with null field + startTs = 99999; + endTs = 99999 + 10; + sessionDataSet = session->executeRawDataQuery(paths, startTs, endTs); + + sessionDataSet->setFetchSize(10); + columns = sessionDataSet->getColumnNames(); + for (const string& column : columns) { + cout << column << " "; + } + cout << endl; + REQUIRE(columns[0] == "Time"); + REQUIRE(columns[1] == paths[0]); + REQUIRE(columns[2] == paths[1]); + REQUIRE(columns[3] == paths[2]); + ts = startTs; + while (sessionDataSet->hasNext()) { + auto rowRecordPtr = sessionDataSet->next(); + cout << rowRecordPtr->toString(); + + vector fields = rowRecordPtr->fields; + REQUIRE(rowRecordPtr->timestamp == ts); + REQUIRE(fields[0].dataType == TSDataType::INT64); + REQUIRE(fields[0].longV.value() == 9); + REQUIRE(fields[1].dataType == TSDataType::UNKNOWN); + REQUIRE(fields[2].dataType == TSDataType::INT64); + REQUIRE(fields[2].longV.value() == 999); + } + + //== Test executeRawDataQuery() with empty data + sessionDataSet = session->executeRawDataQuery(paths, 100000, 110000); + sessionDataSet->setFetchSize(1); + REQUIRE(sessionDataSet->hasNext() == false); } TEST_CASE("Test executeLastDataQuery ", "[testExecuteLastDataQuery]") { - CaseReporter cr("testExecuteLastDataQuery"); - prepareTimeseries(); - - string deviceId = "root.test.d1"; - vector measurements = {"s1", "s2", "s3"}; - vector types = {TSDataType::INT64, TSDataType::INT64, TSDataType::INT64}; - - long total_count = 5000; - vector values; - int64_t valueArray[3]; - for (long time = -total_count; time < total_count; time++) { - valueArray[0] = time; - valueArray[1] = time * 2; - valueArray[2] = time * 3; - values.clear(); - values.push_back((char*)&valueArray[0]); - values.push_back((char*)&valueArray[1]); - values.push_back((char*)&valueArray[2]); - session->insertRecord(deviceId, time, measurements, types, values); - if (time == 100) { //insert 1 big timestamp data for gen unseq data. - valueArray[0] = 9; - valueArray[2] = 999; - values.clear(); - values.push_back((char*)&valueArray[0]); - values.push_back((char*)&valueArray[2]); - vector measurements2 = {"s1", "s3"}; - vector types2 = {TSDataType::INT64, TSDataType::INT64}; - session->insertRecord(deviceId, 99999, measurements2, types2, values); - } - } - - int64_t tsCheck[3] = {99999, 4999, 99999}; - std::vector valueCheck = {"9", "9998", "999"}; - - vector paths; - paths.push_back("root.test.d1.s1"); - paths.push_back("root.test.d1.s2"); - paths.push_back("root.test.d1.s3"); - - //== Test executeLastDataQuery() without lastTime - unique_ptr sessionDataSet = session->executeLastDataQuery(paths); - sessionDataSet->setFetchSize(1); - - vector columns = sessionDataSet->getColumnNames(); - for (const string &column : columns) { - cout << column << " " ; - } - cout << endl; - - int index = 0; - while (sessionDataSet->hasNext()) { - auto rowRecordPtr = sessionDataSet->next(); - cout << rowRecordPtr->toString(); - - vector fields = rowRecordPtr->fields; - REQUIRE(rowRecordPtr->timestamp == tsCheck[index]); - REQUIRE(fields[0].stringV.value() == paths[index]); - REQUIRE(fields[1].stringV.value() == valueCheck[index]); - REQUIRE(fields[2].stringV.value() == "INT64"); - index++; - } - - //== Test executeLastDataQuery() with negative lastTime - sessionDataSet = session->executeLastDataQuery(paths, -200); - sessionDataSet->setFetchSize(1); - columns = sessionDataSet->getColumnNames(); - for (const string &column : columns) { - cout << column << " " ; - } - cout << endl; - - index = 0; - while (sessionDataSet->hasNext()) { - auto rowRecordPtr = sessionDataSet->next(); - cout << rowRecordPtr->toString(); - - vector fields = rowRecordPtr->fields; - REQUIRE(rowRecordPtr->timestamp == tsCheck[index]); - REQUIRE(fields[0].stringV.value() == paths[index]); - REQUIRE(fields[1].stringV.value() == valueCheck[index]); - REQUIRE(fields[2].stringV.value() == "INT64"); - index++; - } - - //== Test executeLastDataQuery() with the lastTime that is > largest timestamp. - sessionDataSet = session->executeLastDataQuery(paths, 100000); - sessionDataSet->setFetchSize(1024); - REQUIRE(sessionDataSet->hasNext() == false); + CaseReporter cr("testExecuteLastDataQuery"); + prepareTimeseries(); + + string deviceId = "root.test.d1"; + vector measurements = {"s1", "s2", "s3"}; + vector types = {TSDataType::INT64, TSDataType::INT64, TSDataType::INT64}; + + long total_count = 5000; + vector values; + int64_t valueArray[3]; + for (long time = -total_count; time < total_count; time++) { + valueArray[0] = time; + valueArray[1] = time * 2; + valueArray[2] = time * 3; + values.clear(); + values.push_back((char*)&valueArray[0]); + values.push_back((char*)&valueArray[1]); + values.push_back((char*)&valueArray[2]); + session->insertRecord(deviceId, time, measurements, types, values); + if (time == 100) { //insert 1 big timestamp data for gen unseq data. + valueArray[0] = 9; + valueArray[2] = 999; + values.clear(); + values.push_back((char*)&valueArray[0]); + values.push_back((char*)&valueArray[2]); + vector measurements2 = {"s1", "s3"}; + vector types2 = {TSDataType::INT64, TSDataType::INT64}; + session->insertRecord(deviceId, 99999, measurements2, types2, values); + } + } + + int64_t tsCheck[3] = {99999, 4999, 99999}; + std::vector valueCheck = {"9", "9998", "999"}; + + vector paths; + paths.push_back("root.test.d1.s1"); + paths.push_back("root.test.d1.s2"); + paths.push_back("root.test.d1.s3"); + + //== Test executeLastDataQuery() without lastTime + unique_ptr sessionDataSet = session->executeLastDataQuery(paths); + sessionDataSet->setFetchSize(1); + + vector columns = sessionDataSet->getColumnNames(); + for (const string& column : columns) { + cout << column << " "; + } + cout << endl; + + int index = 0; + while (sessionDataSet->hasNext()) { + auto rowRecordPtr = sessionDataSet->next(); + cout << rowRecordPtr->toString(); + + vector fields = rowRecordPtr->fields; + REQUIRE(rowRecordPtr->timestamp == tsCheck[index]); + REQUIRE(fields[0].stringV.value() == paths[index]); + REQUIRE(fields[1].stringV.value() == valueCheck[index]); + REQUIRE(fields[2].stringV.value() == "INT64"); + index++; + } + + //== Test executeLastDataQuery() with negative lastTime + sessionDataSet = session->executeLastDataQuery(paths, -200); + sessionDataSet->setFetchSize(1); + columns = sessionDataSet->getColumnNames(); + for (const string& column : columns) { + cout << column << " "; + } + cout << endl; + + index = 0; + while (sessionDataSet->hasNext()) { + auto rowRecordPtr = sessionDataSet->next(); + cout << rowRecordPtr->toString(); + + vector fields = rowRecordPtr->fields; + REQUIRE(rowRecordPtr->timestamp == tsCheck[index]); + REQUIRE(fields[0].stringV.value() == paths[index]); + REQUIRE(fields[1].stringV.value() == valueCheck[index]); + REQUIRE(fields[2].stringV.value() == "INT64"); + index++; + } + + //== Test executeLastDataQuery() with the lastTime that is > largest timestamp. + sessionDataSet = session->executeLastDataQuery(paths, 100000); + sessionDataSet->setFetchSize(1024); + REQUIRE(sessionDataSet->hasNext() == false); } // Helper function for comparing TEndPoint with detailed error message -void assertTEndPointEqual(const TEndPoint& actual, - const std::string& expectedIp, - int expectedPort, - const char* file, - int line) { - if (actual.ip != expectedIp || actual.port != expectedPort) { - std::stringstream ss; - ss << "\nTEndPoint mismatch:\nExpected: " << expectedIp << ":" << expectedPort - << "\nActual: " << actual.ip << ":" << actual.port; - Catch::SourceLineInfo location(file, line); - Catch::AssertionHandler handler("TEndPoint comparison", location, ss.str(), Catch::ResultDisposition::Normal); - handler.handleMessage(Catch::ResultWas::ExplicitFailure, ss.str()); - handler.complete(); - } +void assertTEndPointEqual(const TEndPoint& actual, const std::string& expectedIp, int expectedPort, + const char* file, int line) { + if (actual.ip != expectedIp || actual.port != expectedPort) { + std::stringstream ss; + ss << "\nTEndPoint mismatch:\nExpected: " << expectedIp << ":" << expectedPort + << "\nActual: " << actual.ip << ":" << actual.port; + Catch::SourceLineInfo location(file, line); + Catch::AssertionHandler handler("TEndPoint comparison", location, ss.str(), + Catch::ResultDisposition::Normal); + handler.handleMessage(Catch::ResultWas::ExplicitFailure, ss.str()); + handler.complete(); + } } // Macro to simplify test assertions -#define REQUIRE_TENDPOINT(actual, expectedIp, expectedPort) \ - assertTEndPointEqual(actual, expectedIp, expectedPort, __FILE__, __LINE__) +#define REQUIRE_TENDPOINT(actual, expectedIp, expectedPort) \ + assertTEndPointEqual(actual, expectedIp, expectedPort, __FILE__, __LINE__) TEST_CASE("UrlUtils - parseTEndPointIpv4AndIpv6Url", "[UrlUtils]") { - // Test valid IPv4 addresses - SECTION("Valid IPv4") { - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("192.168.1.1:8080"), "192.168.1.1", 8080); - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("10.0.0.1:80"), "10.0.0.1", 80); - } - - // Test valid IPv6 addresses - SECTION("Valid IPv6") { - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("[2001:db8::1]:8080"), "2001:db8::1", 8080); - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("[::1]:80"), "::1", 80); - } - - // Test hostnames - SECTION("Hostnames") { - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("localhost:8080"), "localhost", 8080); - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("example.com:443"), "example.com", 443); - } - - // Test edge cases - SECTION("Edge cases") { - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url(""), "", 0); - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("127.0.0.1"), "127.0.0.1", 0); - } - - // Test invalid inputs - SECTION("Invalid inputs") { - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("192.168.1.1:abc"), "192.168.1.1:abc", 0); - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("]invalid[:80"), "]invalid[", 80); - } - - // Test port ranges - SECTION("Port ranges") { - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("localhost:0"), "localhost", 0); - REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("127.0.0.1:65535"), "127.0.0.1", 65535); - } + // Test valid IPv4 addresses + SECTION("Valid IPv4") { + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("192.168.1.1:8080"), "192.168.1.1", + 8080); + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("10.0.0.1:80"), "10.0.0.1", 80); + } + + // Test valid IPv6 addresses + SECTION("Valid IPv6") { + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("[2001:db8::1]:8080"), "2001:db8::1", + 8080); + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("[::1]:80"), "::1", 80); + } + + // Test hostnames + SECTION("Hostnames") { + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("localhost:8080"), "localhost", 8080); + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("example.com:443"), "example.com", + 443); + } + + // Test edge cases + SECTION("Edge cases") { + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url(""), "", 0); + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("127.0.0.1"), "127.0.0.1", 0); + } + + // Test invalid inputs + SECTION("Invalid inputs") { + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("192.168.1.1:abc"), "192.168.1.1:abc", + 0); + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("]invalid[:80"), "]invalid[", 80); + } + + // Test port ranges + SECTION("Port ranges") { + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("localhost:0"), "localhost", 0); + REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("127.0.0.1:65535"), "127.0.0.1", + 65535); + } } TEST_CASE("TsBlock deserialize rejects truncated malicious payload", "[TsBlockDeserialize]") { - std::string data(18, '\0'); - data[3] = '\x10'; - REQUIRE_THROWS_AS(TsBlock::deserialize(data), IoTDBException); + std::string data(18, '\0'); + data[3] = '\x10'; + REQUIRE_THROWS_AS(TsBlock::deserialize(data), IoTDBException); } \ No newline at end of file diff --git a/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp b/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp index 94f956b56ea43..678ec5f6b574e 100644 --- a/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp +++ b/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp @@ -30,249 +30,246 @@ static int global_test_tag = 0; class CaseReporter { public: - CaseReporter(const char* caseNameArg) : caseName(caseNameArg) { - test_tag = global_test_tag++; - std::cout << "Test " << test_tag << ": " << caseName << std::endl; - } + CaseReporter(const char* caseNameArg) : caseName(caseNameArg) { + test_tag = global_test_tag++; + std::cout << "Test " << test_tag << ": " << caseName << std::endl; + } - ~CaseReporter() { - std::cout << "Test " << test_tag << ": " << caseName << " Done" << std::endl << std::endl; - } + ~CaseReporter() { + std::cout << "Test " << test_tag << ": " << caseName << " Done" << std::endl << std::endl; + } private: - const char* caseName; - int test_tag; + const char* caseName; + int test_tag; }; TEST_CASE("Create table success", "[createTable]") { - // REQUIRE(true); - CaseReporter cr("createTable"); - 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->executeNonQueryStatement("USE \"db1\""); - session->executeNonQueryStatement("CREATE TABLE table0 (" - "tag1 string tag," - "attr1 string attribute," - "m1 double field)"); - unique_ptr sessionDataSet = session->executeQueryStatement("SHOW TABLES"); - sessionDataSet->setFetchSize(1024); - bool tableExist = false; - while (sessionDataSet->hasNext()) { - if (sessionDataSet->next()->fields[0].stringV.value() == "table0") { - tableExist = true; - break; - } + // REQUIRE(true); + CaseReporter cr("createTable"); + 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->executeNonQueryStatement("USE \"db1\""); + session->executeNonQueryStatement("CREATE TABLE table0 (" + "tag1 string tag," + "attr1 string attribute," + "m1 double field)"); + unique_ptr sessionDataSet = session->executeQueryStatement("SHOW TABLES"); + sessionDataSet->setFetchSize(1024); + bool tableExist = false; + while (sessionDataSet->hasNext()) { + if (sessionDataSet->next()->fields[0].stringV.value() == "table0") { + tableExist = true; + break; } - REQUIRE(tableExist == true); + } + REQUIRE(tableExist == true); } TEST_CASE("Test TableSession builder with nodeUrls", "[SessionBuilderInit]") { - CaseReporter cr("TableSessionInitWithNodeUrls"); + CaseReporter cr("TableSessionInitWithNodeUrls"); - std::vector nodeUrls = {"127.0.0.1:6667"}; - auto builder = std::unique_ptr(new TableSessionBuilder()); - std::shared_ptr session = - std::shared_ptr( - builder - ->username("root") - ->password("root") - ->nodeUrls(nodeUrls) - ->build() - ); - session->open(); + std::vector nodeUrls = {"127.0.0.1:6667"}; + auto builder = std::unique_ptr(new TableSessionBuilder()); + std::shared_ptr session = std::shared_ptr( + builder->username("root")->password("root")->nodeUrls(nodeUrls)->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->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(); + session->close(); } TEST_CASE("Test insertRelationalTablet", "[testInsertRelationalTablet]") { - CaseReporter cr("testInsertRelationalTablet"); - session->executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS db1"); - session->executeNonQueryStatement("USE db1"); - session->executeNonQueryStatement("DROP TABLE IF EXISTS table1"); - session->executeNonQueryStatement("CREATE TABLE table1 (" - "tag1 string tag," - "attr1 string attribute," - "m1 double field)"); - vector> schemaList; - schemaList.push_back(make_pair("tag1", TSDataType::TEXT)); - schemaList.push_back(make_pair("attr1", TSDataType::TEXT)); - schemaList.push_back(make_pair("m1", TSDataType::DOUBLE)); - vector columnTypes = {ColumnCategory::TAG, ColumnCategory::ATTRIBUTE, ColumnCategory::FIELD}; + CaseReporter cr("testInsertRelationalTablet"); + session->executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS db1"); + session->executeNonQueryStatement("USE db1"); + session->executeNonQueryStatement("DROP TABLE IF EXISTS table1"); + session->executeNonQueryStatement("CREATE TABLE table1 (" + "tag1 string tag," + "attr1 string attribute," + "m1 double field)"); + vector> schemaList; + schemaList.push_back(make_pair("tag1", TSDataType::TEXT)); + schemaList.push_back(make_pair("attr1", TSDataType::TEXT)); + schemaList.push_back(make_pair("m1", TSDataType::DOUBLE)); + vector columnTypes = {ColumnCategory::TAG, ColumnCategory::ATTRIBUTE, + ColumnCategory::FIELD}; - int64_t timestamp = 0; - Tablet tablet("table1", schemaList, columnTypes, 15); + int64_t timestamp = 0; + Tablet tablet("table1", schemaList, columnTypes, 15); - for (int row = 0; row < 15; row++) { - int rowIndex = tablet.rowSize++; - tablet.timestamps[rowIndex] = timestamp + row; - string data = "tag:"; - data += to_string(row); - tablet.addValue(0, rowIndex, data); - data = "attr:"; - data += to_string(row); - tablet.addValue(1, rowIndex, data); - double value = row * 1.1; - tablet.addValue(2, rowIndex, value); - if (tablet.rowSize == tablet.maxRowNumber) { - session->insert(tablet, true); - tablet.reset(); - } + for (int row = 0; row < 15; row++) { + int rowIndex = tablet.rowSize++; + tablet.timestamps[rowIndex] = timestamp + row; + string data = "tag:"; + data += to_string(row); + tablet.addValue(0, rowIndex, data); + data = "attr:"; + data += to_string(row); + tablet.addValue(1, rowIndex, data); + double value = row * 1.1; + tablet.addValue(2, rowIndex, value); + if (tablet.rowSize == tablet.maxRowNumber) { + session->insert(tablet, true); + tablet.reset(); } + } - if (tablet.rowSize != 0) { - session->insert(tablet, true); - tablet.reset(); - } - session->executeNonQueryStatement("FLUSH"); + if (tablet.rowSize != 0) { + session->insert(tablet, true); + tablet.reset(); + } + session->executeNonQueryStatement("FLUSH"); - int cnt = 0; - unique_ptr sessionDataSet = session->executeQueryStatement("SELECT * FROM table1 order by time"); - while (sessionDataSet->hasNext()) { - auto rowRecord = sessionDataSet->next(); - REQUIRE(rowRecord->fields[1].stringV.value() == string("tag:") + to_string(cnt)); - REQUIRE(rowRecord->fields[2].stringV.value() == string("attr:") + to_string(cnt)); - REQUIRE(fabs(rowRecord->fields[3].doubleV.value() - cnt * 1.1) < 0.0001); - cnt++; - } - REQUIRE(cnt == 15); + int cnt = 0; + unique_ptr sessionDataSet = + session->executeQueryStatement("SELECT * FROM table1 order by time"); + while (sessionDataSet->hasNext()) { + auto rowRecord = sessionDataSet->next(); + REQUIRE(rowRecord->fields[1].stringV.value() == string("tag:") + to_string(cnt)); + REQUIRE(rowRecord->fields[2].stringV.value() == string("attr:") + to_string(cnt)); + REQUIRE(fabs(rowRecord->fields[3].doubleV.value() - cnt * 1.1) < 0.0001); + cnt++; + } + REQUIRE(cnt == 15); } TEST_CASE("Test RelationalTabletTsblockRead", "[testRelationalTabletTsblockRead]") { - CaseReporter cr("testRelationalTabletTsblockRead"); - session->executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS db1"); - session->executeNonQueryStatement("USE db1"); - session->executeNonQueryStatement("DROP TABLE IF EXISTS table1"); - session->executeNonQueryStatement("CREATE TABLE table1 (" - "field1 BOOLEAN field," - "field2 INT32 field," - "field3 INT64 field," - "field4 FLOAT field," - "field5 DOUBLE field," - "field6 TEXT field," - "field7 TIMESTAMP field," - "field8 DATE field," - "field9 BLOB field," - "field10 STRING field)"); - - vector> schemaList; - schemaList.push_back(make_pair("field1", TSDataType::BOOLEAN)); - schemaList.push_back(make_pair("field2", TSDataType::INT32)); - schemaList.push_back(make_pair("field3", TSDataType::INT64)); - schemaList.push_back(make_pair("field4", TSDataType::FLOAT)); - schemaList.push_back(make_pair("field5", TSDataType::DOUBLE)); - schemaList.push_back(make_pair("field6", TSDataType::TEXT)); - schemaList.push_back(make_pair("field7", TSDataType::TIMESTAMP)); - schemaList.push_back(make_pair("field8", TSDataType::DATE)); - schemaList.push_back(make_pair("field9", TSDataType::BLOB)); - schemaList.push_back(make_pair("field10", TSDataType::STRING)); + CaseReporter cr("testRelationalTabletTsblockRead"); + session->executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS db1"); + session->executeNonQueryStatement("USE db1"); + session->executeNonQueryStatement("DROP TABLE IF EXISTS table1"); + session->executeNonQueryStatement("CREATE TABLE table1 (" + "field1 BOOLEAN field," + "field2 INT32 field," + "field3 INT64 field," + "field4 FLOAT field," + "field5 DOUBLE field," + "field6 TEXT field," + "field7 TIMESTAMP field," + "field8 DATE field," + "field9 BLOB field," + "field10 STRING field)"); - vector columnTypes(10, ColumnCategory::FIELD); + vector> schemaList; + schemaList.push_back(make_pair("field1", TSDataType::BOOLEAN)); + schemaList.push_back(make_pair("field2", TSDataType::INT32)); + schemaList.push_back(make_pair("field3", TSDataType::INT64)); + schemaList.push_back(make_pair("field4", TSDataType::FLOAT)); + schemaList.push_back(make_pair("field5", TSDataType::DOUBLE)); + schemaList.push_back(make_pair("field6", TSDataType::TEXT)); + schemaList.push_back(make_pair("field7", TSDataType::TIMESTAMP)); + schemaList.push_back(make_pair("field8", TSDataType::DATE)); + schemaList.push_back(make_pair("field9", TSDataType::BLOB)); + schemaList.push_back(make_pair("field10", TSDataType::STRING)); - int64_t timestamp = 0; - int maxRowNumber = 50000; - Tablet tablet("table1", schemaList, columnTypes, maxRowNumber); + vector columnTypes(10, ColumnCategory::FIELD); - for (int row = 0; row < maxRowNumber; row++) { - int rowIndex = tablet.rowSize++; - tablet.timestamps[rowIndex] = timestamp + row; - tablet.addValue(0, rowIndex, row % 2 == 0); - tablet.addValue(1, rowIndex, static_cast(row)); - tablet.addValue(2, rowIndex, static_cast(timestamp)); - tablet.addValue(3, rowIndex, static_cast(row * 1.1f)); - tablet.addValue(4, rowIndex, static_cast(row * 1.1f)); - tablet.addValue(5, rowIndex, "text_" + to_string(row)); - tablet.addValue(6, rowIndex, static_cast(timestamp)); - tablet.addValue(7, rowIndex, boost::gregorian::date(2025, 5, 15)); - tablet.addValue(8, rowIndex, "blob_" + to_string(row)); - tablet.addValue(9, rowIndex, "string_" + to_string(row)); + int64_t timestamp = 0; + int maxRowNumber = 50000; + Tablet tablet("table1", schemaList, columnTypes, maxRowNumber); - if (row % 2 == 0) { - for (int col = 0; col <= 9; col++) { - tablet.bitMaps[col].mark(row); - } - } + for (int row = 0; row < maxRowNumber; row++) { + int rowIndex = tablet.rowSize++; + tablet.timestamps[rowIndex] = timestamp + row; + tablet.addValue(0, rowIndex, row % 2 == 0); + tablet.addValue(1, rowIndex, static_cast(row)); + tablet.addValue(2, rowIndex, static_cast(timestamp)); + tablet.addValue(3, rowIndex, static_cast(row * 1.1f)); + tablet.addValue(4, rowIndex, static_cast(row * 1.1f)); + tablet.addValue(5, rowIndex, "text_" + to_string(row)); + tablet.addValue(6, rowIndex, static_cast(timestamp)); + tablet.addValue(7, rowIndex, boost::gregorian::date(2025, 5, 15)); + tablet.addValue(8, rowIndex, "blob_" + to_string(row)); + tablet.addValue(9, rowIndex, "string_" + to_string(row)); - if (tablet.rowSize == tablet.maxRowNumber) { - session->insert(tablet, true); - tablet.reset(); - } + if (row % 2 == 0) { + for (int col = 0; col <= 9; col++) { + tablet.bitMaps[col].mark(row); + } } - if (tablet.rowSize != 0) { - session->insert(tablet, true); - tablet.reset(); + if (tablet.rowSize == tablet.maxRowNumber) { + session->insert(tablet, true); + tablet.reset(); } - session->executeNonQueryStatement("FLUSH"); + } + + if (tablet.rowSize != 0) { + session->insert(tablet, true); + tablet.reset(); + } + session->executeNonQueryStatement("FLUSH"); - unique_ptr sessionDataSet = session->executeQueryStatement("SELECT * FROM table1 order by time"); - auto dataIter = sessionDataSet->getIterator(); - int rowNum = 0; - timestamp = 0; - while (dataIter.next()) { - if (rowNum % 2 == 0) { - REQUIRE_FALSE(dataIter.getBooleanByIndex(2).is_initialized()); - REQUIRE_FALSE(dataIter.getIntByIndex(3).is_initialized()); - REQUIRE_FALSE(dataIter.getLongByIndex(4).is_initialized()); - REQUIRE_FALSE(dataIter.getFloatByIndex(5).is_initialized()); - REQUIRE_FALSE(dataIter.getDoubleByIndex(6).is_initialized()); - REQUIRE_FALSE(dataIter.getStringByIndex(7).is_initialized()); - REQUIRE_FALSE(dataIter.getTimestampByIndex(8).is_initialized()); - REQUIRE_FALSE(dataIter.getDateByIndex(9).is_initialized()); - REQUIRE_FALSE(dataIter.getStringByIndex(10).is_initialized()); - REQUIRE_FALSE(dataIter.getStringByIndex(11).is_initialized()); - } else { - REQUIRE(dataIter.getLongByIndex(1).value() == timestamp + rowNum); - REQUIRE(dataIter.getBooleanByIndex(2).value() == (rowNum % 2 == 0)); - REQUIRE(dataIter.getIntByIndex(3).value() == static_cast(rowNum)); - REQUIRE(dataIter.getLongByIndex(4).value() == static_cast(timestamp)); - REQUIRE(fabs(dataIter.getFloatByIndex(5).value() - rowNum * 1.1f) < 0.1f); - REQUIRE(fabs(dataIter.getDoubleByIndex(6).value() - rowNum * 1.1f) < 0.1); - REQUIRE(dataIter.getStringByIndex(7).value() == "text_" + to_string(rowNum)); - REQUIRE(dataIter.getTimestampByIndex(8).value() == static_cast(timestamp)); - REQUIRE(dataIter.getDateByIndex(9).value() == boost::gregorian::date(2025, 5, 15)); - REQUIRE(dataIter.getStringByIndex(10).value() == "blob_" + to_string(rowNum)); - REQUIRE(dataIter.getStringByIndex(11).value() == "string_" + to_string(rowNum)); - } - rowNum++; + unique_ptr sessionDataSet = + session->executeQueryStatement("SELECT * FROM table1 order by time"); + auto dataIter = sessionDataSet->getIterator(); + int rowNum = 0; + timestamp = 0; + while (dataIter.next()) { + if (rowNum % 2 == 0) { + REQUIRE_FALSE(dataIter.getBooleanByIndex(2).is_initialized()); + REQUIRE_FALSE(dataIter.getIntByIndex(3).is_initialized()); + REQUIRE_FALSE(dataIter.getLongByIndex(4).is_initialized()); + REQUIRE_FALSE(dataIter.getFloatByIndex(5).is_initialized()); + REQUIRE_FALSE(dataIter.getDoubleByIndex(6).is_initialized()); + REQUIRE_FALSE(dataIter.getStringByIndex(7).is_initialized()); + REQUIRE_FALSE(dataIter.getTimestampByIndex(8).is_initialized()); + REQUIRE_FALSE(dataIter.getDateByIndex(9).is_initialized()); + REQUIRE_FALSE(dataIter.getStringByIndex(10).is_initialized()); + REQUIRE_FALSE(dataIter.getStringByIndex(11).is_initialized()); + } else { + REQUIRE(dataIter.getLongByIndex(1).value() == timestamp + rowNum); + REQUIRE(dataIter.getBooleanByIndex(2).value() == (rowNum % 2 == 0)); + REQUIRE(dataIter.getIntByIndex(3).value() == static_cast(rowNum)); + REQUIRE(dataIter.getLongByIndex(4).value() == static_cast(timestamp)); + REQUIRE(fabs(dataIter.getFloatByIndex(5).value() - rowNum * 1.1f) < 0.1f); + REQUIRE(fabs(dataIter.getDoubleByIndex(6).value() - rowNum * 1.1f) < 0.1); + REQUIRE(dataIter.getStringByIndex(7).value() == "text_" + to_string(rowNum)); + REQUIRE(dataIter.getTimestampByIndex(8).value() == static_cast(timestamp)); + REQUIRE(dataIter.getDateByIndex(9).value() == boost::gregorian::date(2025, 5, 15)); + REQUIRE(dataIter.getStringByIndex(10).value() == "blob_" + to_string(rowNum)); + REQUIRE(dataIter.getStringByIndex(11).value() == "string_" + to_string(rowNum)); } - REQUIRE(rowNum == maxRowNumber); + rowNum++; + } + REQUIRE(rowNum == maxRowNumber); - sessionDataSet = session->executeQueryStatement("SELECT * FROM table1 order by time"); - rowNum = 0; - timestamp = 0; - while (sessionDataSet->hasNext()) { - auto record = sessionDataSet->next(); - if (rowNum % 2 == 0) { - REQUIRE_FALSE(record->fields[1].boolV.is_initialized()); - REQUIRE_FALSE(record->fields[2].intV.is_initialized()); - REQUIRE_FALSE(record->fields[3].longV.is_initialized()); - REQUIRE_FALSE(record->fields[4].floatV.is_initialized()); - REQUIRE_FALSE(record->fields[5].doubleV.is_initialized()); - REQUIRE_FALSE(record->fields[6].stringV.is_initialized()); - REQUIRE_FALSE(record->fields[7].longV.is_initialized()); - REQUIRE_FALSE(record->fields[8].dateV.is_initialized()); - REQUIRE_FALSE(record->fields[9].stringV.is_initialized()); - REQUIRE_FALSE(record->fields[10].stringV.is_initialized()); - } else { - REQUIRE(record->fields[1].boolV.value() == (rowNum % 2 == 0)); - REQUIRE(record->fields[2].intV.value() == static_cast(rowNum)); - REQUIRE(record->fields[3].longV.value() == static_cast(timestamp)); - REQUIRE(fabs(record->fields[4].floatV.value() - rowNum * 1.1f) < 0.1f); - REQUIRE(fabs(record->fields[5].doubleV.value() - rowNum * 1.1f) < 0.1); - REQUIRE(record->fields[6].stringV.value() == "text_" + to_string(rowNum)); - REQUIRE(record->fields[7].longV.value() == static_cast(timestamp)); - REQUIRE(record->fields[8].dateV.value() == boost::gregorian::date(2025, 5, 15)); - REQUIRE(record->fields[9].stringV.value() == "blob_" + to_string(rowNum)); - REQUIRE(record->fields[10].stringV.value() == "string_" + to_string(rowNum)); - } - rowNum++; + sessionDataSet = session->executeQueryStatement("SELECT * FROM table1 order by time"); + rowNum = 0; + timestamp = 0; + while (sessionDataSet->hasNext()) { + auto record = sessionDataSet->next(); + if (rowNum % 2 == 0) { + REQUIRE_FALSE(record->fields[1].boolV.is_initialized()); + REQUIRE_FALSE(record->fields[2].intV.is_initialized()); + REQUIRE_FALSE(record->fields[3].longV.is_initialized()); + REQUIRE_FALSE(record->fields[4].floatV.is_initialized()); + REQUIRE_FALSE(record->fields[5].doubleV.is_initialized()); + REQUIRE_FALSE(record->fields[6].stringV.is_initialized()); + REQUIRE_FALSE(record->fields[7].longV.is_initialized()); + REQUIRE_FALSE(record->fields[8].dateV.is_initialized()); + REQUIRE_FALSE(record->fields[9].stringV.is_initialized()); + REQUIRE_FALSE(record->fields[10].stringV.is_initialized()); + } else { + REQUIRE(record->fields[1].boolV.value() == (rowNum % 2 == 0)); + REQUIRE(record->fields[2].intV.value() == static_cast(rowNum)); + REQUIRE(record->fields[3].longV.value() == static_cast(timestamp)); + REQUIRE(fabs(record->fields[4].floatV.value() - rowNum * 1.1f) < 0.1f); + REQUIRE(fabs(record->fields[5].doubleV.value() - rowNum * 1.1f) < 0.1); + REQUIRE(record->fields[6].stringV.value() == "text_" + to_string(rowNum)); + REQUIRE(record->fields[7].longV.value() == static_cast(timestamp)); + REQUIRE(record->fields[8].dateV.value() == boost::gregorian::date(2025, 5, 15)); + REQUIRE(record->fields[9].stringV.value() == "blob_" + to_string(rowNum)); + REQUIRE(record->fields[10].stringV.value() == "string_" + to_string(rowNum)); } - REQUIRE(rowNum == maxRowNumber); + rowNum++; + } + REQUIRE(rowNum == maxRowNumber); } diff --git a/iotdb-client/client-cpp/src/test/main.cpp b/iotdb-client/client-cpp/src/test/main.cpp index 44a4aec135855..1bc3425882fa8 100644 --- a/iotdb-client/client-cpp/src/test/main.cpp +++ b/iotdb-client/client-cpp/src/test/main.cpp @@ -27,32 +27,32 @@ std::shared_ptr session; struct SessionListener : Catch::TestEventListenerBase { - using TestEventListenerBase::TestEventListenerBase; - - void testCaseStarting(Catch::TestCaseInfo const &testInfo) override { - if (!session) { - SessionBuilder builder; - session = builder.host("127.0.0.1") - ->rpcPort(6667) - ->username("root") - ->password("root") - ->useSSL(false) - ->build(); - } else { - session->open(false); - } + using TestEventListenerBase::TestEventListenerBase; + + void testCaseStarting(Catch::TestCaseInfo const& testInfo) override { + if (!session) { + SessionBuilder builder; + session = builder.host("127.0.0.1") + ->rpcPort(6667) + ->username("root") + ->password("root") + ->useSSL(false) + ->build(); + } else { + session->open(false); } + } - void testCaseEnded(Catch::TestCaseStats const &testCaseStats) override { - if (session) { - session->close(); - } + void testCaseEnded(Catch::TestCaseStats const& testCaseStats) override { + if (session) { + session->close(); } + } - void testRunEnded(Catch::TestRunStats const &testRunStats) override { - // Release session before static/global teardown on Windows. - session.reset(); - } + void testRunEnded(Catch::TestRunStats const& testRunStats) override { + // Release session before static/global teardown on Windows. + session.reset(); + } }; -CATCH_REGISTER_LISTENER( SessionListener ) \ No newline at end of file +CATCH_REGISTER_LISTENER(SessionListener) \ No newline at end of file diff --git a/iotdb-client/client-cpp/src/test/main_Relational.cpp b/iotdb-client/client-cpp/src/test/main_Relational.cpp index e45e7a38644d3..de808c23224e6 100644 --- a/iotdb-client/client-cpp/src/test/main_Relational.cpp +++ b/iotdb-client/client-cpp/src/test/main_Relational.cpp @@ -25,31 +25,28 @@ std::shared_ptr session; struct SessionListener : Catch::TestEventListenerBase { - using TestEventListenerBase::TestEventListenerBase; - - void testCaseStarting(Catch::TestCaseInfo const& testInfo) override { - if (!session) { - TableSessionBuilder builder; - session = builder.host("127.0.0.1") - ->rpcPort(6667) - ->username("root") - ->password("root") - ->build(); - } else { - session->open(); - } + using TestEventListenerBase::TestEventListenerBase; + + void testCaseStarting(Catch::TestCaseInfo const& testInfo) override { + if (!session) { + TableSessionBuilder builder; + session = + builder.host("127.0.0.1")->rpcPort(6667)->username("root")->password("root")->build(); + } else { + session->open(); } + } - void testCaseEnded(Catch::TestCaseStats const& testCaseStats) override { - if (session) { - session->close(); - } + void testCaseEnded(Catch::TestCaseStats const& testCaseStats) override { + if (session) { + session->close(); } + } - void testRunEnded(Catch::TestRunStats const& testRunStats) override { - // Release session before static/global teardown on Windows. - session.reset(); - } + void testRunEnded(Catch::TestRunStats const& testRunStats) override { + // Release session before static/global teardown on Windows. + session.reset(); + } }; CATCH_REGISTER_LISTENER(SessionListener) \ No newline at end of file diff --git a/iotdb-client/client-cpp/src/test/main_c.cpp b/iotdb-client/client-cpp/src/test/main_c.cpp index 5a712d0c83034..056b1f49b4ca1 100644 --- a/iotdb-client/client-cpp/src/test/main_c.cpp +++ b/iotdb-client/client-cpp/src/test/main_c.cpp @@ -26,26 +26,27 @@ CSession* g_session = nullptr; struct CSessionListener : Catch::TestEventListenerBase { - using TestEventListenerBase::TestEventListenerBase; + using TestEventListenerBase::TestEventListenerBase; - void testCaseStarting(Catch::TestCaseInfo const& testInfo) override { - g_session = ts_session_new("127.0.0.1", 6667, "root", "root"); - REQUIRE(g_session != nullptr); - TsStatus st = ts_session_open(g_session); - if (st != TS_OK) { - ts_session_destroy(g_session); - g_session = nullptr; - FAIL("ts_session_open failed; ensure distribution is built and IoTDB listens on 127.0.0.1:6667"); - } + void testCaseStarting(Catch::TestCaseInfo const& testInfo) override { + g_session = ts_session_new("127.0.0.1", 6667, "root", "root"); + REQUIRE(g_session != nullptr); + TsStatus st = ts_session_open(g_session); + if (st != TS_OK) { + ts_session_destroy(g_session); + g_session = nullptr; + FAIL("ts_session_open failed; ensure distribution is built and IoTDB listens on " + "127.0.0.1:6667"); } + } - void testCaseEnded(Catch::TestCaseStats const& testCaseStats) override { - if (g_session) { - ts_session_close(g_session); - ts_session_destroy(g_session); - g_session = nullptr; - } + void testCaseEnded(Catch::TestCaseStats const& testCaseStats) override { + if (g_session) { + ts_session_close(g_session); + ts_session_destroy(g_session); + g_session = nullptr; } + } }; CATCH_REGISTER_LISTENER(CSessionListener) diff --git a/iotdb-client/client-cpp/src/test/main_c_Relational.cpp b/iotdb-client/client-cpp/src/test/main_c_Relational.cpp index 80067663bbbb9..68759f97c96cc 100644 --- a/iotdb-client/client-cpp/src/test/main_c_Relational.cpp +++ b/iotdb-client/client-cpp/src/test/main_c_Relational.cpp @@ -26,26 +26,27 @@ CTableSession* g_table_session = nullptr; struct CTableSessionListener : Catch::TestEventListenerBase { - using TestEventListenerBase::TestEventListenerBase; + using TestEventListenerBase::TestEventListenerBase; - void testCaseStarting(Catch::TestCaseInfo const& testInfo) override { - g_table_session = ts_table_session_new("127.0.0.1", 6667, "root", "root", ""); - REQUIRE(g_table_session != nullptr); - TsStatus st = ts_table_session_open(g_table_session); - if (st != TS_OK) { - ts_table_session_destroy(g_table_session); - g_table_session = nullptr; - FAIL("ts_table_session_open failed; ensure distribution is built and IoTDB listens on 127.0.0.1:6667"); - } + void testCaseStarting(Catch::TestCaseInfo const& testInfo) override { + g_table_session = ts_table_session_new("127.0.0.1", 6667, "root", "root", ""); + REQUIRE(g_table_session != nullptr); + TsStatus st = ts_table_session_open(g_table_session); + if (st != TS_OK) { + ts_table_session_destroy(g_table_session); + g_table_session = nullptr; + FAIL("ts_table_session_open failed; ensure distribution is built and IoTDB listens on " + "127.0.0.1:6667"); } + } - void testCaseEnded(Catch::TestCaseStats const& testCaseStats) override { - if (g_table_session) { - ts_table_session_close(g_table_session); - ts_table_session_destroy(g_table_session); - g_table_session = nullptr; - } + void testCaseEnded(Catch::TestCaseStats const& testCaseStats) override { + if (g_table_session) { + ts_table_session_close(g_table_session); + ts_table_session_destroy(g_table_session); + g_table_session = nullptr; } + } }; CATCH_REGISTER_LISTENER(CTableSessionListener) diff --git a/pom.xml b/pom.xml index dc46047da2efd..d9b8d7000d84b 100644 --- a/pom.xml +++ b/pom.xml @@ -149,7 +149,8 @@ apache false - 2.43.0 + 2.44.5 + 17.0.6 1.6.14 chmod