blob: 65152615cd7dfe5f11840cf1ffa3c879efc6a196 [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 C CXX)
find_package(TsFile 2.5.0 CONFIG REQUIRED)
add_executable(tsfile_example main.c)
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
```C
ERRNO code = 0;
char* table_name = "table1";
// Create table schema to describe a table in a tsfile.
TableSchema table_schema;
table_schema.table_name = strdup(table_name);
table_schema.column_num = 3;
table_schema.column_schemas =
(ColumnSchema*)malloc(sizeof(ColumnSchema) * 3);
table_schema.column_schemas[0] =
(ColumnSchema){.column_name = strdup("id1"),
.data_type = TS_DATATYPE_STRING,
.column_category = TAG};
table_schema.column_schemas[1] =
(ColumnSchema){.column_name = strdup("id2"),
.data_type = TS_DATATYPE_STRING,
.column_category = TAG};
table_schema.column_schemas[2] =
(ColumnSchema){.column_name = strdup("s1"),
.data_type = TS_DATATYPE_INT32,
.column_category = FIELD};
// Create a file with specify path to write tsfile.
WriteFile file = write_file_new("test_c.tsfile", &code);
HANDLE_ERROR(code);
// Create tsfile writer with specify table schema.
TsFileWriter writer = tsfile_writer_new(file, &table_schema, &code);
HANDLE_ERROR(code);
```
### Write Data
```C
// Create tablet to insert data.
Tablet tablet =
tablet_new((char*[]){"id1", "id2", "s1"},
(TSDataType[]){TS_DATATYPE_STRING, TS_DATATYPE_STRING,
TS_DATATYPE_INT32},
3, 5);
for (int row = 0; row < 5; row++) {
Timestamp timestamp = row;
tablet_add_timestamp(tablet, row, timestamp);
tablet_add_value_by_name_string(tablet, row, "id1", "id_field_1");
tablet_add_value_by_name_string(tablet, row, "id2", "id_field_2");
tablet_add_value_by_name_int32_t(tablet, row, "s1", row);
}
// Write tablet data.
HANDLE_ERROR(tsfile_writer_write(writer, tablet));
// Free tablet.
free_tablet(&tablet);
// Free table schema we used before.
free_table_schema(table_schema);
```
### Close File
```C
// Close writer.
HANDLE_ERROR(tsfile_writer_close(writer));
// Close write file after closing writer.
free_write_file(&file);
```
### Sample Code
The sample code of using these interfaces is in <https://github.com/apache/tsfile/blob/develop/cpp/examples/c_examples/demo_write.c>
## Reading Process
### Construct TsFileReader
```C
ERRNO code = 0;
char* table_name = "table1";
// Create tsfile reader with specify tsfile's path
TsFileReader reader = tsfile_reader_new("test_c.tsfile", &code);
HANDLE_ERROR(code);
```
### Construct Query
```C
ResultSet ret = tsfile_query_table(
reader, table_name, (char*[]){"id1", "id2", "s1"}, 3, 0, 10, &code);
HANDLE_ERROR(code);
if (ret == NULL) {
HANDLE_ERROR(RET_INVALID_QUERY);
}
```
### Query Data
```C
// Get query result metadata: column name and datatype
ResultSetMetaData metadata = tsfile_result_set_get_metadata(ret);
int column_num = tsfile_result_set_metadata_get_column_num(metadata);
for (int i = 1; i <= column_num; i++) {
printf("column:%s, datatype:%d\n", tsfile_result_set_metadata_get_column_name(metadata, i),
tsfile_result_set_metadata_get_data_type(metadata, i));
}
// Get data by column name or index.
while (tsfile_result_set_next(ret, &code) && code == RET_OK) {
// Timestamp at column 1 and column index begin from 1.
Timestamp timestamp =
tsfile_result_set_get_value_by_index_int64_t(ret, 1);
printf("%ld\n", timestamp);
for (int i = 1; i <= column_num; i++) {
if (tsfile_result_set_is_null_by_index(ret, i)) {
printf(" null ");
} else {
switch (tsfile_result_set_metadata_get_data_type(metadata, i)) {
case TS_DATATYPE_BOOLEAN:
printf("%d\n", tsfile_result_set_get_value_by_index_bool(
ret, i));
break;
case TS_DATATYPE_INT32:
printf("%d\n",
tsfile_result_set_get_value_by_index_int32_t(ret,
i));
break;
case TS_DATATYPE_INT64:
printf("%ld\n",
tsfile_result_set_get_value_by_index_int64_t(ret,
i));
break;
case TS_DATATYPE_FLOAT:
printf("%f\n", tsfile_result_set_get_value_by_index_float(
ret, i));
break;
case TS_DATATYPE_DOUBLE:
printf("%lf\n",
tsfile_result_set_get_value_by_index_double(ret,
i));
break;
case TS_DATATYPE_STRING:
printf("%s\n",
tsfile_result_set_get_value_by_index_string(ret,
i));
break;
default:
printf("unknown_type");
break;
}
}
}
}
// Free query meta data
free_result_set_meta_data(metadata);
// Free query handler.
free_tsfile_result_set(&ret);
```
### Close File
```C
// Close tsfile reader.
tsfile_reader_close(reader);
```
### Sample Code
The sample code of using these interfaces is in <https://github.com/apache/tsfile/blob/develop/cpp/examples/c_examples/demo_read.c>
> 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-C.md). If you need information regarding the tree model, please contact us.