blob: baf92e297f273647774ecd443ccc36db8cb0d341 [file] [view]
<!--
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.
-->
# Quick Start - C++
## Installation
C/C++ 2.5.0 provides prebuilt runtimes, development packages, and the CLI; **building TsFile with Maven is no longer a prerequisite**.
Application development requires a C/C++ compiler. The installed CMake package supports CMake 3.11+; selecting the Windows runtime requires CMake 3.15+.
Running only the CLI does not require a compiler. See the [download and installation page](../../../Download/README.md#cpp-packages) for all artifacts and checksum instructions.
### Choose an installation method
| Platform | Packages for C/C++ development | Instructions |
| --- | --- | --- |
| Ubuntu 22.04 / 24.04 | `tsfile` + `tsfile-dev` | [Download, verify, and install DEBs](../../../Download/README.md#cpp-ubuntu) |
| AlmaLinux 9 | `tsfile` + `tsfile-devel` | [Download, verify, and install RPMs](../../../Download/README.md#cpp-rpm) |
| macOS | Homebrew Formula or SDK archive | [Homebrew installation](../../../Download/README.md#cpp-homebrew), including library, headers, and CLI |
| Linux / macOS | Complete SDK archive | Install without changing system directories, as shown below |
| Windows | Matching-architecture SDK/CLI ZIP | [Windows installation](../../../Download/README.md#cpp-windows); retain the DLL and `bin/` layout |
`tsfile-dev` / `tsfile-devel` are development-file packages, not development-release channels. The CLI is in `tsfile-tools`.
After downloading and verifying the DEB/RPM files, install the local runtime and development packages, for example:
```bash
# Ubuntu amd64; use matching filenames for arm64
sudo apt install ./tsfile_2.5.0-1_amd64.deb ./tsfile-dev_2.5.0-1_amd64.deb
```
```bash
# AlmaLinux 9 x86_64; use matching filenames for aarch64
sudo dnf install ./tsfile-2.5.0-1.el9.x86_64.rpm ./tsfile-devel-2.5.0-1.el9.x86_64.rpm
```
### Extract an SDK (Linux / macOS)
Run in an empty directory. Use `macos12-arm64` on Apple Silicon Macs, `macos12-x86_64` on Intel Macs,
or `manylinux_2_28-x86_64` / `manylinux_2_28-aarch64` on Linux, according to architecture.
```bash
VERSION=2.5.0
PLATFORM=macos12-arm64
ARCHIVE="tsfile-sdk-${PLATFORM}-${VERSION}.tar.gz"
URL="https://packages.apache.org/artifactory/tsfile/sdk/release/versions/${VERSION}/${PLATFORM}/${ARCHIVE}"
curl --fail --location "$URL" --output "$ARCHIVE"
SHA256="$(curl --fail --silent --show-error "$URL.sha256")"
if command -v sha256sum >/dev/null 2>&1; then
printf '%s %s\n' "$SHA256" "$ARCHIVE" | sha256sum -c - || exit 1
else
printf '%s %s\n' "$SHA256" "$ARCHIVE" | shasum -a 256 -c - || exit 1
fi
mkdir tsfile-sdk
tar -xzf "$ARCHIVE" -C tsfile-sdk --strip-components=1
export TSFILE_HOME="$PWD/tsfile-sdk"
export PATH="$TSFILE_HOME/bin:$PATH"
tsfile-cli --version
```
For Homebrew, first import the Formula as described on the download page, then set `TSFILE_HOME="$(brew --prefix local/tsfile250/tsfile)"`.
SDKs contain `include/`, `lib/`, `lib/cmake/TsFile/`, `lib/pkgconfig/`, `bin/`, and `share/`; preserve their relative layout.
### CMake integration
Use the installed package's exported target in your project's `CMakeLists.txt`, rather than finding just the library file with `find_library`:
```cmake
cmake_minimum_required(VERSION 3.11)
project(tsfile_example LANGUAGES CXX)
find_package(TsFile 2.5.0 CONFIG REQUIRED)
add_executable(tsfile_example main.cpp)
target_link_libraries(tsfile_example PRIVATE TsFile::tsfile)
```
```bash
cmake -S . -B build -DCMAKE_PREFIX_PATH="$TSFILE_HOME"
cmake --build build --config Release
```
For DEB/RPM installations in standard system locations, `CMAKE_PREFIX_PATH` is normally unnecessary. The exported target supplies include directories and required compile definitions.
On Windows, use matching-architecture MSVC and CMake 3.15+ to select the package's Release `/MT` runtime:
```powershell
cmake -S . -B build -DCMAKE_PREFIX_PATH="$env:TSFILE_HOME" `
-DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded
cmake --build build --config Release
```
### pkg-config (Linux / macOS)
Locate metadata under an SDK or Homebrew prefix; system packages are normally discoverable without this assignment:
```bash
export PKG_CONFIG_PATH="$TSFILE_HOME/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
pkg-config --modversion libtsfile
pkg-config --cflags --libs libtsfile
```
### Optional: build from source
Build from source only to change TsFile or customize build options. This requires JDK 17+, CMake, a C++11 compiler, and Make/Ninja;
the repository supplies a Maven wrapper. The source-built version follows your checked-out branch or commit, not necessarily the 2.5.0 binary packages above.
```bash
git clone https://github.com/apache/tsfile.git
cd tsfile
./mvnw clean package -P with-cpp -Dbuild.test=OFF
cmake --install cpp/target/build --prefix "$PWD/tsfile-sdk"
```
Use `mvnw.cmd` on Windows. Then point `CMAKE_PREFIX_PATH` at the installed `tsfile-sdk` prefix;
do not mix source-tree headers with an installed library from a different version. See [TsFile CLI](../Tools/Tsfile-CLI.md) for CLI installation and usage.
## Writing Process
### Construct TsFileWriter
```cpp
std::string file_name = "test.tsfile";
storage::libtsfile_init();
std::string table_name = "table1";
// Create a file with specify path to write tsfile.
storage::WriteFile file;
int flags = O_WRONLY | O_CREAT | O_TRUNC;
#ifdef _WIN32
flags |= O_BINARY;
#endif
mode_t mode = 0666;
file.create("test_cpp.tsfile", flags, mode);
// Create table schema to describe a table in a tsfile.
auto* schema = new storage::TableSchema(
table_name,
{
common::ColumnSchema("id1", common::STRING, common::UNCOMPRESSED,
common::PLAIN, common::ColumnCategory::TAG),
common::ColumnSchema("id2", common::STRING, common::UNCOMPRESSED,
common::PLAIN, common::ColumnCategory::TAG),
common::ColumnSchema("s1", common::INT64, common::UNCOMPRESSED,
common::PLAIN, common::ColumnCategory::FIELD),
});
// Create a file with specify path to write tsfile.
auto* writer = new storage::TsFileTableWriter(&file, schema);
```
### Write Data
```cpp
// Create tablet to insert data.
storage::Tablet tablet(
table_name, {"id1", "id2", "s1"},
{common::STRING, common::STRING, common::INT64},
{common::ColumnCategory::TAG, common::ColumnCategory::TAG,
common::ColumnCategory::FIELD},
10);
for (int row = 0; row < 5; row++) {
long timestamp = row;
tablet.add_timestamp(row, timestamp);
tablet.add_value(row, "id1", "id1_filed_1");
tablet.add_value(row, "id2", "id1_filed_2");
tablet.add_value(row, "s1", static_cast<int64_t>(row));
}
// Write tablet data.
writer->write_table(tablet);
// Flush data
writer->flush();
```
### Close File
```cpp
writer->close()
```
### Sample Code
The sample code of using these interfaces is in <https://github.com/apache/tsfile/blob/develop/cpp/examples/cpp_examples/demo_write.cpp>
## Query Process
### Construct TsFileReader
```cpp
int code = 0;
storage::libtsfile_init();
std::string table_name = "table1";
// Create tsfile reader and open tsfile with specify path.
storage::TsFileReader reader;
reader.open("test_cpp.tsfile");
```
### Construct Query Request
```cpp
// Query data with tsfile reader.
storage::ResultSet* temp_ret = nullptr;
std::vector<std::string> columns;
columns.emplace_back("id1");
columns.emplace_back("id2");
columns.emplace_back("s1");
auto table_schema = reader.get_table_schema(table_name);
storage::Filter* tag_filter1 = storage::TagFilterBuilder(table_schema.get()).eq("id1", "id1_filed_1");
storage::Filter* tag_filter2 = storage::TagFilterBuilder(table_schema.get()).eq("id2", "id1_filed_2");
storage::Filter* tag_filter = storage::TagFilterBuilder(table_schema.get()).and_filter(tag_filter1, tag_filter2);
// Column vector contains the columns you want to select.
reader.query(table_name, columns, 0, 100, temp_ret, tag_filter);
```
### Query Data
```cpp
// Get query handler.
auto ret = dynamic_cast<storage::TableResultSet*>(temp_ret);
// Metadata in query handler.
auto metadata = ret->get_metadata();
int column_num = metadata->get_column_count();
for (int i = 1; i <= column_num; i++) {
std::cout << "column name: " << metadata->get_column_name(i)
<< std::endl;
std::cout << "column type: "
<< std::to_string(metadata->get_column_type(i)) << std::endl;
}
// Check and get next data.
bool has_next = false;
while ((code = ret->next(has_next)) == common::E_OK && has_next) {
// Timestamp at column 1 and column index begin from 1.
Timestamp timestamp = ret->get_value<Timestamp>(1);
for (int i = 1; i <= column_num; i++) {
if (ret->is_null(i)) {
std::cout << "null" << std::endl;
} else {
switch (metadata->get_column_type(i)) {
case common::BOOLEAN:
std::cout << ret->get_value<bool>(i) << std::endl;
break;
case common::INT32:
std::cout << ret->get_value<int32_t>(i) << std::endl;
break;
case common::INT64:
std::cout << ret->get_value<int64_t>(i) << std::endl;
break;
case common::FLOAT:
std::cout << ret->get_value<float>(i) << std::endl;
break;
case common::DOUBLE:
std::cout << ret->get_value<double>(i) << std::endl;
break;
case common::STRING:
std::cout << ret->get_value<common::String*>(i)
->to_std_string()
<< std::endl;
break;
default:;
}
}
}
}
```
### Close File
```cpp
// Close query result set.
ret->close();
// Close reader.
reader.close();
```
### Sample Code
The sample code of using these interfaces is in <https://github.com/apache/tsfile/blob/develop/cpp/examples/cpp_examples/demo_read.cpp>
> Note: The above read/write examples are all based on the table model interface. For details about the interface definition, please refer to [C++ Interface Definition](./InterfaceDefinition/InterfaceDefinition-CPP.md). If you need information regarding the tree model, please contact us.