This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/tsfile.git
The following commit(s) were added to refs/heads/develop by this push:
new 0f1ab168 Example c cpp (#418)
0f1ab168 is described below
commit 0f1ab1683b7baa82c4539b5840414f6988f2a868
Author: Colin Lee <[email protected]>
AuthorDate: Fri Feb 28 09:23:17 2025 +0800
Example c cpp (#418)
* examples.
tmpc ode.
tmp code.
fix issue.
* add example.
* fix some c issues.
* fix some error.
* fix c
* fix some error.
* fix some issue.
* fix file.
* fix some example issue.
* Fix windows.
* fix code style.
* fix tmp code.
* fix error.
* remove file.
---
cpp/examples/CMakeLists.txt | 21 +-
cpp/examples/README.md | 79 +++
cpp/examples/build.sh | 2 +-
cpp/examples/c_examples/c_examples.c | 133 -----
cpp/examples/c_examples/c_examples.h | 15 +-
cpp/examples/c_examples/demo_read.c | 110 ++++
cpp/examples/c_examples/demo_write.c | 96 ++++
cpp/examples/cpp_examples/cpp_examples.h | 11 +
cpp/examples/cpp_examples/demo_read.cpp | 128 ++---
cpp/examples/cpp_examples/demo_write.cpp | 125 ++---
cpp/examples/examples.cc | 2 +
cpp/examples/test_cpp.tsfile | Bin 0 -> 447 bytes
cpp/src/common/db_common.h | 2 +
cpp/src/common/schema.h | 6 +-
cpp/src/common/tablet.cc | 120 +++--
cpp/src/cwrapper/errno_define.h | 77 +++
cpp/src/cwrapper/tsfile_cwrapper.cc | 585 +++++++++++++--------
cpp/src/cwrapper/tsfile_cwrapper.h | 358 +++++++++++--
.../reader/block/single_device_tsblock_reader.cc | 7 +-
cpp/src/reader/table_result_set.cc | 1 +
cpp/src/utils/db_utils.h | 8 +
cpp/src/writer/tsfile_table_writer.h | 1 +
cpp/src/writer/tsfile_writer.cc | 104 ++--
cpp/src/writer/tsfile_writer.h | 53 +-
cpp/test/cwrapper/cwrapper_test.cc | 242 +++++----
25 files changed, 1525 insertions(+), 761 deletions(-)
diff --git a/cpp/examples/CMakeLists.txt b/cpp/examples/CMakeLists.txt
index 4b433c96..75b92692 100644
--- a/cpp/examples/CMakeLists.txt
+++ b/cpp/examples/CMakeLists.txt
@@ -20,13 +20,32 @@ cmake_minimum_required(VERSION 3.10)
project(examples)
message("Running in exampes directory")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+
+# TsFile include dir
set(SDK_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/../src/)
message("SDK_INCLUDE_DIR: ${SDK_INCLUDE_DIR}")
+
+# TsFile shared object dir
set(SDK_LIB_DIR_RELEASE ${PROJECT_SOURCE_DIR}/../build/Release/lib)
message("SDK_LIB_DIR_RELEASE: ${SDK_LIB_DIR_RELEASE}")
+set(SDK_LIB_DIR_DEBUG ${PROJECT_SOURCE_DIR}/../build/Debug/lib)
+message("SDK_LIB_DIR_DEBUG: ${SDK_LIB_DIR_DEBUG}")
+include_directories(${PROJECT_SOURCE_DIR}/../third_party/antlr4-cpp-runtime-4/runtime/src)
+
+set(BUILD_TYPE "Debug")
include_directories(${SDK_INCLUDE_DIR})
-find_library(my_tsfile_lib NAMES tsfile PATHS ${SDK_LIB_DIR_RELEASE}
NO_DEFAULT_PATH REQUIRED)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g")
+set(CMAKE_CXX_FLAGS_DEBUG" ${CMAKE_CXX_FLAGS} -O0 -g")
+
+# Find libtsfile in SDK_LIB_RIR
+if (BUILD_TYPE STREQUAL "Release")
+ find_library(my_tsfile_lib NAMES tsfile PATHS ${SDK_LIB_DIR_RELEASE}
NO_DEFAULT_PATH REQUIRED)
+elseif(BUILD_TYPE STREQUAL "Debug")
+ find_library(my_tsfile_lib NAMES tsfile PATHS ${SDK_LIB_DIR_DEBUG}
NO_DEFAULT_PATH REQUIRED)
+endif ()
add_subdirectory(cpp_examples)
add_subdirectory(c_examples)
diff --git a/cpp/examples/README.md b/cpp/examples/README.md
new file mode 100644
index 00000000..7b20d5f4
--- /dev/null
+++ b/cpp/examples/README.md
@@ -0,0 +1,79 @@
+<!--
+
+ 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.
+
+-->
+
+# TsFile Reader/Writer Integration Guide
+
+## 1. Building TSFile Shared Library
+
+Build Methods (Choose either approach)
+
+### Method 1: Maven Build
+Execute from the project root directory:
+
+```BASH
+mvn package -P with-cpp clean verify
+```
+Output location: cpp/target/build/lib
+
+If maven is not installed, may use 'mvnw' in linux/macos or 'mvnw.cmd' in win
instead"
+
+### Method 2: Script Build
+Run the build script:
+
+```BASH
+bash build.sh
+```
+Output location: cpp/build/Release/lib
+
+## Project Configuration
+### CMake Integration
+
+Add to your CMakeLists.txt:
+
+```CMAKE
+find_library(TSFILE_LIB NAMES tsfile PATHS ${SDK_LIB} REQUIRED)
+target_link_libraries(your_target ${TSFILE_LIB})
+```
+
+Note: Set ${SDK_LIB} to your TSFile library directory.
+
+## 3. Implementation Examples
+
+### Directory Structure
+```TEXT
+ ├── CMakeLists.txt
+ ├── c_examples/
+ │ ├── demo_write.c # C write implementation
+ │ └── demo_read.c # C read implementation
+ ├── cpp_examples/
+ │ ├── demo_write.cpp # C++ write implementation
+ │ └── demo_read.cpp # C++ read implementation
+ └── examples.cc # Combined use cases
+```
+
+### Code References
+Writing TSFiles:\
+C: c_examples/demo_write.c\
+C++: cpp_examples/demo_write.cpp
+
+Reading TSFiles:\
+C: c_examples/demo_read.c\
+C++: cpp_examples/demo_read.cpp
\ No newline at end of file
diff --git a/cpp/examples/build.sh b/cpp/examples/build.sh
index bf4a3c45..36cf44ae 100644
--- a/cpp/examples/build.sh
+++ b/cpp/examples/build.sh
@@ -28,5 +28,5 @@ else
fi
-cmake ../../ -DUSE_CPP11=$use_cpp11
+cmake ../../ -DBUILD_TYPE=$build_type
make
\ No newline at end of file
diff --git a/cpp/examples/c_examples/c_examples.c
b/cpp/examples/c_examples/c_examples.c
deleted file mode 100644
index 8e5f8d2d..00000000
--- a/cpp/examples/c_examples/c_examples.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.
- */
-
-#include "c_examples.h"
-
-#include <fcntl.h>
-#include <malloc.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#define HANDLE_ERROR(err_no) \
- do { \
- if (err_no != 0) { \
- printf("get err no: %d", err_no); \
- return err_no; \
- } \
- } while (0)
-
-ErrorCode write_tsfile() {
- ErrorCode err_code;
- CTsFileWriter writer;
- if (access("c_rw.tsfile", 0) == 0) {
- if (remove("test.tsfile") != 0) {
- printf("Failed to delete test.tsfile file\n");
- return -1;
- }
- }
- writer = ts_writer_open("c_rw.tsfile", &err_code);
- if (NULL == writer) {
- return err_code;
- }
- ColumnSchema columnSchema;
- columnSchema.name = "temperature";
- columnSchema.column_def = TS_TYPE_INT32;
- err_code =
- tsfile_register_table_column(writer, "test_table", &columnSchema);
- HANDLE_ERROR(err_code);
- TableSchema tableSchema;
- tableSchema.column_num = 3;
- tableSchema.table_name = "test_table";
- tableSchema.column_schema =
- (ColumnSchema **)malloc(tableSchema.column_num * sizeof(TableSchema
*));
- tableSchema.column_schema[0] = (ColumnSchema
*)malloc(sizeof(ColumnSchema));
- tableSchema.column_schema[0]->column_def = TS_TYPE_DOUBLE;
- tableSchema.column_schema[0]->name = "level";
- tableSchema.column_schema[1] = (ColumnSchema
*)malloc(sizeof(ColumnSchema));
- tableSchema.column_schema[1]->column_def = TS_TYPE_BOOLEAN;
- tableSchema.column_schema[1]->name = "up";
- tableSchema.column_schema[2] = (ColumnSchema
*)malloc(sizeof(ColumnSchema));
- tableSchema.column_schema[2]->column_def = TS_TYPE_FLOAT;
- tableSchema.column_schema[2]->name = "humi";
- err_code = tsfile_register_table(writer, &tableSchema);
- free(tableSchema.column_schema[0]);
- free(tableSchema.column_schema[1]);
- free(tableSchema.column_schema[2]);
- free(tableSchema.column_schema);
- HANDLE_ERROR(err_code);
- printf("register table success\n");
- TsFileRowData rowData = create_tsfile_row("test_table", 1, 4);
- insert_data_into_tsfile_row_double(rowData, "level", 10);
- insert_data_into_tsfile_row_float(rowData, "humi", 10.0f);
- insert_data_into_tsfile_row_boolean(rowData, "up", true);
- insert_data_into_tsfile_row_int32(rowData, "temperature", 10);
- err_code = tsfile_write_row_data(writer, rowData);
-
- rowData = create_tsfile_row("test_table", 2, 4);
- insert_data_into_tsfile_row_double(rowData, "level", 12);
- err_code = tsfile_write_row_data(writer, rowData);
-
- for (int ind = 10; ind < 2000; ind++) {
- rowData = create_tsfile_row("test_table", ind, 4);
- insert_data_into_tsfile_row_double(rowData, "level", 12 + ind);
- insert_data_into_tsfile_row_float(rowData, "humi", 12.0f + ind);
- insert_data_into_tsfile_row_boolean(rowData, "up", true);
- insert_data_into_tsfile_row_int32(rowData, "temperature", 12 + ind);
- err_code = tsfile_write_row_data(writer, rowData);
- }
- printf("writer row data success\n");
- HANDLE_ERROR(err_code);
- HANDLE_ERROR(tsfile_flush_data(writer));
- printf("flush data success\n");
- HANDLE_ERROR(ts_writer_close(writer));
- printf("close writer success\n");
- return 0;
-}
-
-ErrorCode read_tsfile() {
- ErrorCode err_code;
- CTsFileReader reader;
- reader = ts_reader_open("c_rw.tsfile", &err_code);
- if (NULL == reader) {
- return err_code;
- }
- const char *columns[] = {"temperature", "level", "up", "humi"};
- // TimeFilterExpression* exp = create_andquery_timefilter();
- // TimeFilterExpression* time_filter = create_time_filter("test_table",
- // "temperature", GT, 11); TimeFilterExpression* time_filter2 =
- // create_time_filter("test_table", "humi", GT, 10); TimeFilterExpression*
- // time_filter3 = create_time_filter("test_table", "level", LE, 20);
- // add_time_filter_to_and_query(exp, time_filter);
- // add_time_filter_to_and_query(exp, time_filter2);
- // add_time_filter_to_and_query(exp, time_filter3);
-
- QueryDataRet ret = ts_reader_query(reader, "test_table", columns, 4, NULL);
- printf("query success\n");
- DataResult *result = ts_next(ret, 20);
- if (result == NULL) {
- printf("get result failed\n");
- return -1;
- }
- print_data_result(result);
- // destory_time_filter_query(exp);
- HANDLE_ERROR(destory_query_dataret(ret));
- HANDLE_ERROR(destory_tablet(result));
- return 0;
-}
diff --git a/cpp/examples/c_examples/c_examples.h
b/cpp/examples/c_examples/c_examples.h
index 3f63803f..ba674778 100644
--- a/cpp/examples/c_examples/c_examples.h
+++ b/cpp/examples/c_examples/c_examples.h
@@ -17,15 +17,22 @@
* under the License.
*/
-#include "cwrapper/TsFile-cwrapper.h"
+#include "cwrapper/errno_define.h"
+#include "cwrapper/tsfile_cwrapper.h"
#ifdef __cplusplus
extern "C" {
#endif
+ERRNO write_tsfile();
+ERRNO read_tsfile();
-ErrorCode write_tsfile();
-ErrorCode read_tsfile();
-
+#define HANDLE_ERROR(err_no) \
+ do { \
+ if (err_no != 0) { \
+ printf("get err no: %d", err_no); \
+ return err_no; \
+ } \
+ } while (0)
#ifdef __cplusplus
}
#endif
diff --git a/cpp/examples/c_examples/demo_read.c
b/cpp/examples/c_examples/demo_read.c
new file mode 100644
index 00000000..1636adbd
--- /dev/null
+++ b/cpp/examples/c_examples/demo_read.c
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "c_examples.h"
+
+// This example shows you how to read tsfile.
+ERRNO read_tsfile() {
+
+ 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);
+
+ 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);
+ }
+
+ // Get query result metadata: column name and datatype
+ ResultSetMetaData metadata = tsfile_result_set_get_metadata(ret);
+ int column_num = metadata.column_num;
+
+ for (int i = 0; i < column_num; i++) {
+ printf("column:%s, datatype:%d\n", metadata.column_names[i],
+ metadata.data_types[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 ", timestamp);
+ for (int i = 1; i < column_num; i++) {
+ if (tsfile_result_set_is_null_by_index(ret, i)) {
+ printf(" null ");
+ } else {
+ switch (metadata.data_types[i]) {
+ case TS_DATATYPE_BOOLEAN:
+ printf("%d", tsfile_result_set_get_value_by_index_bool(
+ ret, i));
+ break;
+ case TS_DATATYPE_INT32:
+ printf("%d",
+
tsfile_result_set_get_value_by_index_int32_t(ret,
+
i));
+ break;
+ case TS_DATATYPE_INT64:
+ printf("%ld",
+
tsfile_result_set_get_value_by_index_int64_t(ret,
+
i));
+ break;
+ case TS_DATATYPE_FLOAT:
+ printf("%f",
tsfile_result_set_get_value_by_index_float(
+ ret, i));
+ break;
+ case TS_DATATYPE_DOUBLE:
+ printf("%lf",
+ tsfile_result_set_get_value_by_index_double(ret,
+ i));
+ break;
+ case TS_DATATYPE_STRING:
+ printf("%s",
+ 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 tsfile reader.
+ tsfile_reader_close(reader);
+
+ return 0;
+}
diff --git a/cpp/examples/c_examples/demo_write.c
b/cpp/examples/c_examples/demo_write.c
new file mode 100644
index 00000000..78c134dc
--- /dev/null
+++ b/cpp/examples/c_examples/demo_write.c
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+#include <malloc.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "c_examples.h"
+
+// This example shows you how to write tsfile.
+ERRNO write_tsfile() {
+ 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,
+ .compression = TS_COMPRESSION_UNCOMPRESSED,
+ .encoding = TS_ENCODING_PLAIN,
+ .column_category = TAG};
+ table_schema.column_schemas[1] =
+ ColumnSchema{.column_name = strdup("id2"),
+ .data_type = TS_DATATYPE_STRING,
+ .compression = TS_COMPRESSION_UNCOMPRESSED,
+ .encoding = TS_ENCODING_PLAIN,
+ .column_category = TAG};
+ table_schema.column_schemas[2] =
+ ColumnSchema{.column_name = strdup("s1"),
+ .data_type = TS_DATATYPE_INT32,
+ .compression = TS_COMPRESSION_UNCOMPRESSED,
+ .encoding = TS_ENCODING_PLAIN,
+ .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);
+
+ // 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 writer.
+ HANDLE_ERROR(tsfile_writer_close(writer));
+
+ // Close write file after closing writer.
+ free_write_file(&file);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/cpp/examples/cpp_examples/cpp_examples.h
b/cpp/examples/cpp_examples/cpp_examples.h
index b2e52aad..b0512e9a 100644
--- a/cpp/examples/cpp_examples/cpp_examples.h
+++ b/cpp/examples/cpp_examples/cpp_examples.h
@@ -22,12 +22,23 @@
#include "common/record.h"
#include "common/row_record.h"
#include "common/schema.h"
+#include "common/tablet.h"
+#include "file/write_file.h"
#include "reader/expression.h"
#include "reader/filter/filter.h"
#include "reader/qds_with_timegenerator.h"
#include "reader/qds_without_timegenerator.h"
#include "reader/tsfile_reader.h"
+#include "writer/tsfile_table_writer.h"
#include "writer/tsfile_writer.h"
+#define HANDLE_ERROR(err_no) \
+ do { \
+ if (err_no != 0) { \
+ printf("get err no: %d", err_no); \
+ return err_no; \
+ } \
+ } while (0)
+
int demo_read();
int demo_write();
diff --git a/cpp/examples/cpp_examples/demo_read.cpp
b/cpp/examples/cpp_examples/demo_read.cpp
index 8fab33f9..4961fb04 100644
--- a/cpp/examples/cpp_examples/demo_read.cpp
+++ b/cpp/examples/cpp_examples/demo_read.cpp
@@ -20,78 +20,82 @@
#include <string>
#include <vector>
+#include "../c_examples/c_examples.h"
#include "cpp_examples.h"
-std::string field_to_string(storage::Field *value) {
- if (value->type_ == common::TEXT) {
- return std::string(value->value_.sval_);
- } else {
- std::stringstream ss;
- switch (value->type_) {
- case common::BOOLEAN:
- ss << (value->value_.bval_ ? "true" : "false");
- break;
- case common::INT32:
- ss << value->value_.ival_;
- break;
- case common::INT64:
- ss << value->value_.lval_;
- break;
- case common::FLOAT:
- ss << value->value_.fval_;
- break;
- case common::DOUBLE:
- ss << value->value_.dval_;
- break;
- case common::NULL_TYPE:
- ss << "NULL";
- break;
- default:
- ASSERT(false);
- break;
- }
- return ss.str();
- }
-}
+using namespace storage;
int demo_read() {
- std::cout << "begin to read tsfile from demo_ts.tsfile" << std::endl;
- std::string device_name = "root.db001.dev001";
- std::string measurement_name = "m001";
- storage::Path p1(device_name, measurement_name);
- std::vector<storage::Path> select_list;
- select_list.push_back(p1);
- storage::QueryExpression *query_expr =
- storage::QueryExpression::create(select_list, nullptr);
- common::init_config_value();
+ int code = 0;
+ libtsfile_init();
+ std::string table_name = "table1";
+
+ // Create tsfile reader and open tsfile with specify path.
storage::TsFileReader reader;
- int ret = reader.open("cpp_rw.tsfile");
+ reader.open("test_cpp.tsfile");
+
+ // 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");
- std::cout << "begin to query expr" << std::endl;
- ASSERT(ret == 0);
- storage::ResultSet *qds = nullptr;
- ret = reader.query(query_expr, qds);
+ // Column vector contains the columns you want to select.
+ HANDLE_ERROR(reader.query(table_name, columns, 0, 100, temp_ret));
- storage::RowRecord *record;
- std::cout << "begin to dump data from tsfile ---" << std::endl;
- int row_cout = 0;
- do {
- if (qds->next()) {
- std::cout << "dump QDS : " << record->get_timestamp() << ",";
- record = qds->get_row_record();
- if (record) {
- int size = record->get_fields()->size();
- for (int i = 0; i < size; ++i) {
- std::cout << field_to_string(record->get_field(i)) << ",";
+ // 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 = 0; i < column_num; i++) {
+ std::cout << "column name: " << metadata->get_column_name(i)
+ << std::endl;
+ std::cout << "column type: " << 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 = 0; 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)
+ << std::endl;
+ break;
+ default:;
}
- std::cout << std::endl;
- row_cout++;
}
- } else {
- break;
}
- } while (true);
+ }
+
+ // Close query result set.
+ ret->close();
- return (0);
+ // Close reader.
+ reader.close();
}
diff --git a/cpp/examples/cpp_examples/demo_write.cpp
b/cpp/examples/cpp_examples/demo_write.cpp
index 17c5cb6b..594309b7 100644
--- a/cpp/examples/cpp_examples/demo_write.cpp
+++ b/cpp/examples/cpp_examples/demo_write.cpp
@@ -17,7 +17,9 @@
* under the License.
*/
+#include <cwrapper/tsfile_cwrapper.h>
#include <time.h>
+#include <writer/tsfile_table_writer.h>
#include <iostream>
#include <random>
@@ -27,88 +29,65 @@
using namespace storage;
-long getNowTime() { return time(nullptr); }
-
-static std::string generate_random_string(int length) {
- std::random_device rd;
- std::mt19937 gen(rd());
- std::uniform_int_distribution<> dis(0, 61);
-
- const std::string chars =
- "0123456789"
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
- std::string random_string;
-
- for (int i = 0; i < length; ++i) {
- random_string += chars[dis(gen)];
- }
-
- return random_string;
-}
-
int demo_write() {
- TsFileWriter* tsfile_writer_ = new TsFileWriter();
+ int code = 0;
libtsfile_init();
- std::string file_name_ = std::string("tsfile_writer_test_") +
- generate_random_string(10) +
- std::string(".tsfile");
+
+ 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;
- tsfile_writer_->open(file_name_, flags, mode);
- remove(file_name_.c_str());
- const int device_num = 50;
- const int measurement_num = 50;
- std::vector<MeasurementSchema> schema_vec[50];
- for (int i = 0; i < device_num; i++) {
- std::string device_name = "test_device" + std::to_string(i);
- schema_vec[i].reserve(measurement_num);
- for (int j = 0; j < measurement_num; j++) {
- std::string measure_name = "measurement" + std::to_string(j);
- schema_vec[i].emplace_back(
- MeasurementSchema(measure_name, common::TSDataType::INT32,
- common::TSEncoding::PLAIN,
- common::CompressionType::UNCOMPRESSED));
- tsfile_writer_->register_timeseries(device_name, schema_vec[i][j]);
- }
- }
+ file.create("test_cpp.tsfile", flags, mode);
- std::cout << "input tablet size" << std::endl;
- int tablet_size;
- std::cin >> tablet_size;
-
- int max_rows = 100000;
- int cur_row = 0;
- long start = getNowTime();
- for (; cur_row < max_rows;) {
- if (cur_row + tablet_size > max_rows) {
- tablet_size = max_rows - cur_row;
- }
- for (int i = 0; i < device_num; i++) {
- std::string device_name = "test_device" + std::to_string(i);
- Tablet tablet(device_name, &schema_vec[i], tablet_size);
- tablet.init();
- for (int row = 0; row < tablet_size; row++) {
- tablet.set_timestamp(row, 16225600 + cur_row + row);
- }
- for (int j = 0; j < measurement_num; j++) {
- for (int row = 0; row < tablet_size; row++) {
- tablet.set_value(row, j, row + cur_row);
- }
- }
- tsfile_writer_->write_tablet(tablet);
- tsfile_writer_->flush();
- }
- cur_row += tablet_size;
- std::cout << "finish writing " << cur_row << " rows" << std::endl;
+ // 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 TsFileTableWriter(&file, schema);
+
+ // Create tablet to insert data.
+ storage::Tablet tablet = storage::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));
}
- tsfile_writer_->close();
- long end = getNowTime();
- printf("interval waitForResults is %ld \n", end - start);
+ // Write tablet data.
+ HANDLE_ERROR(writer->write_table(tablet));
+
+ // Flush data
+ HANDLE_ERROR(writer->flush());
+
+ // Close writer.
+ HANDLE_ERROR(writer->close());
+
+ delete writer;
+
return 0;
}
diff --git a/cpp/examples/examples.cc b/cpp/examples/examples.cc
index 845d3f78..edbd819a 100644
--- a/cpp/examples/examples.cc
+++ b/cpp/examples/examples.cc
@@ -22,8 +22,10 @@
int main() {
// C++ examples
+ // std::cout << "begin write and read tsfile by cpp" << std::endl;
demo_write();
demo_read();
+ std::cout << "begin write and read tsfile by c" << std::endl;
// C examples
write_tsfile();
read_tsfile();
diff --git a/cpp/examples/test_cpp.tsfile b/cpp/examples/test_cpp.tsfile
new file mode 100644
index 00000000..e8410db8
Binary files /dev/null and b/cpp/examples/test_cpp.tsfile differ
diff --git a/cpp/src/common/db_common.h b/cpp/src/common/db_common.h
index 572b998b..b06c8fe4 100644
--- a/cpp/src/common/db_common.h
+++ b/cpp/src/common/db_common.h
@@ -134,6 +134,8 @@ FORCE_INLINE CompressionType
get_default_compression_for_type(TSDataType type) {
return UNCOMPRESSED;
} else if (type == common::TEXT) {
return UNCOMPRESSED;
+ } else if (type == common::STRING) {
+ return UNCOMPRESSED;
} else {
ASSERT(false);
}
diff --git a/cpp/src/common/schema.h b/cpp/src/common/schema.h
index 15822041..3a67b7fa 100644
--- a/cpp/src/common/schema.h
+++ b/cpp/src/common/schema.h
@@ -184,7 +184,7 @@ class TableSchema {
* in the table.
*/
TableSchema(const std::string &table_name,
- const std::vector<common::ColumnSchema> &column_schemas) {
+ const std::vector<common::ColumnSchema>
&column_schemas):table_name_(table_name) {
to_lowercase_inplace(table_name_);
for (const common::ColumnSchema &column_schema : column_schemas) {
column_schemas_.emplace_back(std::make_shared<MeasurementSchema>(
@@ -280,6 +280,10 @@ class TableSchema {
return ret;
}
+ int32_t get_columns_num() const {
+ return column_schemas_.size();
+ }
+
int find_column_index(const std::string &column_name) {
std::string lower_case_column_name = to_lower(column_name);
auto it = column_pos_index_.find(lower_case_column_name);
diff --git a/cpp/src/common/tablet.cc b/cpp/src/common/tablet.cc
index 181e9920..54f39df5 100644
--- a/cpp/src/common/tablet.cc
+++ b/cpp/src/common/tablet.cc
@@ -43,33 +43,40 @@ int Tablet::init() {
}
}
ASSERT(schema_map_.size() == schema_count);
- value_matrix_ = (ValueMatrixEntry *)malloc(sizeof(ValueMatrixEntry) *
schema_count);
+ value_matrix_ =
+ (ValueMatrixEntry *)malloc(sizeof(ValueMatrixEntry) * schema_count);
for (size_t c = 0; c < schema_count; ++c) {
const MeasurementSchema &schema = schema_vec_->at(c);
switch (schema.data_type_) {
case BOOLEAN:
- value_matrix_[c].bool_data = (bool
*)malloc(get_data_type_size(schema.data_type_) * max_row_num_);
+ value_matrix_[c].bool_data = (bool *)malloc(
+ get_data_type_size(schema.data_type_) * max_row_num_);
break;
case INT32:
- value_matrix_[c].int32_data = (int32_t
*)malloc(get_data_type_size(schema.data_type_) * max_row_num_);
+ value_matrix_[c].int32_data = (int32_t *)malloc(
+ get_data_type_size(schema.data_type_) * max_row_num_);
break;
case INT64:
- value_matrix_[c].int64_data = (int64_t
*)malloc(get_data_type_size(schema.data_type_) * max_row_num_);
+ value_matrix_[c].int64_data = (int64_t *)malloc(
+ get_data_type_size(schema.data_type_) * max_row_num_);
break;
case FLOAT:
- value_matrix_[c].float_data = (float
*)malloc(get_data_type_size(schema.data_type_) * max_row_num_);
+ value_matrix_[c].float_data = (float *)malloc(
+ get_data_type_size(schema.data_type_) * max_row_num_);
break;
case DOUBLE:
- value_matrix_[c].double_data = (double
*)malloc(get_data_type_size(schema.data_type_) * max_row_num_);
+ value_matrix_[c].double_data = (double *)malloc(
+ get_data_type_size(schema.data_type_) * max_row_num_);
break;
case STRING: {
- value_matrix_[c].string_data = (common::String
*)malloc(sizeof(String) * max_row_num_);
+ value_matrix_[c].string_data =
+ (common::String *)malloc(sizeof(String) * max_row_num_);
break;
}
default:
ASSERT(false);
- return E_INVALID_ARG;
+ return E_INVALID_ARG;
}
}
@@ -92,24 +99,24 @@ void Tablet::destroy() {
switch (schema.data_type_) {
case INT32:
free(value_matrix_[c].int32_data);
- break;
+ break;
case INT64:
free(value_matrix_[c].int64_data);
- break;
+ break;
case FLOAT:
free(value_matrix_[c].float_data);
- break;
+ break;
case DOUBLE:
free(value_matrix_[c].double_data);
- break;
+ break;
case BOOLEAN:
free(value_matrix_[c].bool_data);
- break;
+ break;
case STRING:
free(value_matrix_[c].string_data);
- break;
+ break;
default:
- break;
+ break;
}
}
free(value_matrix_);
@@ -133,11 +140,12 @@ int Tablet::add_timestamp(uint32_t row_index, int64_t
timestamp) {
return E_OK;
}
-void* Tablet::get_value(int row_index, uint32_t schema_index,
common::TSDataType& data_type) const {
+void *Tablet::get_value(int row_index, uint32_t schema_index,
+ common::TSDataType &data_type) const {
if (UNLIKELY(schema_index >= schema_vec_->size())) {
return nullptr;
}
- const MeasurementSchema& schema = schema_vec_->at(schema_index);
+ const MeasurementSchema &schema = schema_vec_->at(schema_index);
ValueMatrixEntry column_values = value_matrix_[schema_index];
data_type = schema.data_type_;
@@ -146,23 +154,23 @@ void* Tablet::get_value(int row_index, uint32_t
schema_index, common::TSDataType
}
switch (schema.data_type_) {
case BOOLEAN: {
- bool* bool_values = column_values.bool_data;
+ bool *bool_values = column_values.bool_data;
return &bool_values[row_index];
}
case INT32: {
- int32_t* int32_values = column_values.int32_data;
+ int32_t *int32_values = column_values.int32_data;
return &int32_values[row_index];
}
case INT64: {
- int64_t* int64_values = column_values.int64_data;
+ int64_t *int64_values = column_values.int64_data;
return &int64_values[row_index];
}
case FLOAT: {
- float* float_values = column_values.float_data;
+ float *float_values = column_values.float_data;
return &float_values[row_index];
}
case DOUBLE: {
- double* double_values = column_values.double_data;
+ double *double_values = column_values.double_data;
return &double_values[row_index];
}
case STRING: {
@@ -175,8 +183,10 @@ void* Tablet::get_value(int row_index, uint32_t
schema_index, common::TSDataType
}
template <>
-void Tablet::process_val(uint32_t row_index, uint32_t schema_index,
common::String val) {
- value_matrix_[schema_index].string_data[row_index].dup_from(val,
page_arena_);
+void Tablet::process_val(uint32_t row_index, uint32_t schema_index,
+ common::String val) {
+ value_matrix_[schema_index].string_data[row_index].dup_from(val,
+ page_arena_);
bitmaps_[schema_index].clear(row_index); /* mark as non-null */
}
@@ -184,20 +194,25 @@ template <typename T>
void Tablet::process_val(uint32_t row_index, uint32_t schema_index, T val) {
switch (schema_vec_->at(schema_index).data_type_) {
case common::BOOLEAN:
- (value_matrix_[schema_index].bool_data)[row_index] =
static_cast<bool>(val);
- break;
+ (value_matrix_[schema_index].bool_data)[row_index] =
+ static_cast<bool>(val);
+ break;
case common::INT32:
- value_matrix_[schema_index].int32_data[row_index] =
static_cast<int32_t>(val);
- break;
+ value_matrix_[schema_index].int32_data[row_index] =
+ static_cast<int32_t>(val);
+ break;
case common::INT64:
- value_matrix_[schema_index].int64_data[row_index] =
static_cast<int64_t>(val);
- break;
+ value_matrix_[schema_index].int64_data[row_index] =
+ static_cast<int64_t>(val);
+ break;
case common::FLOAT:
- value_matrix_[schema_index].float_data[row_index] =
static_cast<float>(val);
- break;
+ value_matrix_[schema_index].float_data[row_index] =
+ static_cast<float>(val);
+ break;
case common::DOUBLE:
- value_matrix_[schema_index].double_data[row_index] =
static_cast<double>(val);
- break;
+ value_matrix_[schema_index].double_data[row_index] =
+ static_cast<double>(val);
+ break;
default:
ASSERT(false);
}
@@ -216,13 +231,13 @@ int Tablet::add_value(uint32_t row_index, uint32_t
schema_index, T val) {
if (GetDataTypeFromTemplateType<T>() == common::INT32 &&
schema.data_type_ == common::INT64) {
process_val(row_index, schema_index,
static_cast<int64_t>(val));
- } else if (GetDataTypeFromTemplateType<T>() == common::FLOAT &&
- schema.data_type_ == common::DOUBLE) {
- process_val(row_index, schema_index,
static_cast<double>(val));
- } else {
- ASSERT(false);
- return E_TYPE_NOT_MATCH;
- }
+ } else if (GetDataTypeFromTemplateType<T>() == common::FLOAT &&
+ schema.data_type_ == common::DOUBLE) {
+ process_val(row_index, schema_index, static_cast<double>(val));
+ } else {
+ ASSERT(false);
+ return E_TYPE_NOT_MATCH;
+ }
} else {
process_val(row_index, schema_index, val);
}
@@ -231,7 +246,8 @@ int Tablet::add_value(uint32_t row_index, uint32_t
schema_index, T val) {
}
template <>
-int Tablet::add_value(uint32_t row_index, uint32_t schema_index,
common::String val) {
+int Tablet::add_value(uint32_t row_index, uint32_t schema_index,
+ common::String val) {
int ret = common::E_OK;
if (UNLIKELY(schema_index >= schema_vec_->size())) {
ASSERT(false);
@@ -255,6 +271,13 @@ int Tablet::add_value(uint32_t row_index, const
std::string &measurement_name,
return ret;
}
+template<>
+int Tablet::add_value(uint32_t row_index,
+ const std::string &measurement_name,
+ const char *val) {
+ add_value(row_index, measurement_name, String(val));
+}
+
template int Tablet::add_value(uint32_t row_index, uint32_t schema_index,
bool val);
template int Tablet::add_value(uint32_t row_index, uint32_t schema_index,
@@ -279,10 +302,11 @@ template int Tablet::add_value(uint32_t row_index,
template int Tablet::add_value(uint32_t row_index,
const std::string &measurement_name, double
val);
template int Tablet::add_value(uint32_t row_index,
- const std::string &measurement_name,
- String val);
+ const std::string &measurement_name, String
val);
+
-void Tablet::set_column_categories(const std::vector<ColumnCategory>&
column_categories) {
+void Tablet::set_column_categories(
+ const std::vector<ColumnCategory> &column_categories) {
column_categories_ = column_categories;
id_column_indexes_.clear();
for (size_t i = 0; i < column_categories_.size(); i++) {
@@ -298,15 +322,15 @@ std::shared_ptr<IDeviceID> Tablet::get_device_id(int i)
const {
id_array.push_back(insert_target_name_);
for (auto id_column_idx : id_column_indexes_) {
common::TSDataType data_type = INVALID_DATATYPE;
- void* value_ptr = get_value(i, id_column_idx, data_type);
+ void *value_ptr = get_value(i, id_column_idx, data_type);
common::String str;
switch (data_type) {
case STRING:
- str = *static_cast<common::String*>(value_ptr);
+ str = *static_cast<common::String *>(value_ptr);
id_array.push_back(str.to_std_string());
break;
default:
- break ;
+ break;
}
}
return std::make_shared<StringArrayDeviceID>(id_array);
diff --git a/cpp/src/cwrapper/errno_define.h b/cpp/src/cwrapper/errno_define.h
new file mode 100644
index 00000000..cf7ad1f4
--- /dev/null
+++ b/cpp/src/cwrapper/errno_define.h
@@ -0,0 +1,77 @@
+/*
+* 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.
+ */
+
+#ifndef CWRAPPER_ERRNO_DEFINRET_H
+#define CWRAPPER_ERRNO_DEFINRET_H
+
+#define RET_OK 0
+#define RET_OOM 1
+#define RET_NOT_EXIST 2
+#define RET_ALREADY_EXIST 3
+#define RET_INVALID_ARG 4
+#define RET_OUT_OF_RANGE 5
+#define RET_PARTIAL_READ 6
+#define RET_NET_BIND_ERR 7
+#define RET_NET_SOCKET_ERR 8
+#define RET_NET_EPOLL_ERR 9
+#define RET_NET_EPOLL_WAIT_ERR 10
+#define RET_NET_RECV_ERR 11
+#define RET_NET_ACCEPT_ERR 12
+#define RET_NET_FCNTL_ERR 13
+#define RET_NET_LISTEN_ERR 14
+#define RET_NET_SEND_ERR 15
+#define RET_PIPRET_ERR 16
+#define RET_THREAD_CREATRET_ERR 17
+#define RET_MUTEX_ERR 18
+#define RET_COND_ERR 19
+#define RET_OVERFLOW 20
+#define RET_NO_MORRET_DATA 21
+#define RET_OUT_OF_ORDER 22
+#define RET_TSBLOCK_TYPRET_NOT_SUPPORTED 23
+#define RET_TSBLOCK_DATA_INCONSISTENCY 24
+#define RET_DDL_UNKNOWN_TYPE 25
+#define RET_TYPRET_NOT_SUPPORTED 26
+#define RET_TYPRET_NOT_MATCH 27
+#define RET_FILRET_OPEN_ERR 28
+#define RET_FILRET_CLOSRET_ERR 29
+#define RET_FILRET_WRITRET_ERR 30
+#define RET_FILRET_READ_ERR 31
+#define RET_FILRET_SYNC_ERR 32
+#define RET_TSFILRET_WRITER_META_ERR 33
+#define RET_FILRET_STAT_ERR 34
+#define RET_TSFILRET_CORRUPTED 35
+#define RET_BUF_NOT_ENOUGH 36
+#define RET_INVALID_PATH 37
+#define RET_NOT_MATCH 38
+#define RET_JSON_INVALID 39
+#define RET_NOT_SUPPORT 40
+#define RET_PARSER_ERR 41
+#define RET_ANALYZRET_ERR 42
+#define RET_INVALID_DATA_POINT 43
+#define RET_DEVICRET_NOT_EXIST 44
+#define RET_MEASUREMENT_NOT_EXIST 45
+#define RET_INVALID_QUERY 46
+#define RET_SDK_QUERY_OPTIMIZRET_ERR 47
+#define RET_COMPRESS_ERR 48
+#define RET_TABLRET_NOT_EXIST 49
+#define RET_COLUMN_NOT_EXIST 50
+#define RET_UNSUPPORTED_ORDER 51
+#define RET_INVALID_NODRET_TYPE 52
+
+#endif /* CWRAPPER_ERRNO_DEFINRET_H */
\ No newline at end of file
diff --git a/cpp/src/cwrapper/tsfile_cwrapper.cc
b/cpp/src/cwrapper/tsfile_cwrapper.cc
index c6c52a16..dbd85b52 100644
--- a/cpp/src/cwrapper/tsfile_cwrapper.cc
+++ b/cpp/src/cwrapper/tsfile_cwrapper.cc
@@ -19,32 +19,105 @@
#include "cwrapper/tsfile_cwrapper.h"
+#include <file/write_file.h>
#include <reader/qds_without_timegenerator.h>
+#include <unistd.h>
+#include <writer/tsfile_table_writer.h>
#include "common/tablet.h"
#include "reader/result_set.h"
#include "reader/tsfile_reader.h"
#include "writer/tsfile_writer.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
static bool is_init = false;
-Tablet tablet_new_with_device(const char *device_id, char **column_name_list,
- TSDataType *data_types, int column_num,
- int max_rows) {
- std::vector<std::string> measurement_list;
- std::vector<common::TSDataType> data_type_list;
- for (int i = 0; i < column_num; i++) {
- measurement_list.emplace_back(column_name_list[i]);
- data_type_list.push_back(
- static_cast<common::TSDataType>(*(data_types + i)));
+void init_tsfile_config() {
+ if (!is_init) {
+ common::init_config_value();
+ is_init = true;
+ }
+}
+
+WriteFile write_file_new(const char *pathname, ERRNO *err_code) {
+ int ret;
+ init_tsfile_config();
+
+ if (access(pathname, F_OK) == 0) {
+ *err_code = common::E_ALREADY_EXIST;
+ return nullptr;
+ }
+
+ int flags = O_RDWR | O_CREAT | O_TRUNC;
+#ifdef _WIN32
+ flags |= O_BINARY;
+#endif
+ mode_t mode = 0666;
+ storage::WriteFile *file = new storage::WriteFile;
+ ret = file->create(pathname, flags, mode);
+ *err_code = ret;
+ return file;
+}
+
+TsFileWriter tsfile_writer_new(WriteFile file, TableSchema *schema,
+ ERRNO *err_code) {
+ init_tsfile_config();
+ std::vector<common::ColumnSchema> column_schemas;
+ for (int i = 0; i < schema->column_num; i++) {
+ ColumnSchema cur_schema = schema->column_schemas[i];
+ column_schemas.emplace_back(common::ColumnSchema(
+ cur_schema.column_name,
+ static_cast<common::TSDataType>(cur_schema.data_type),
+ static_cast<common::CompressionType>(cur_schema.compression),
+ static_cast<common::TSEncoding>(cur_schema.encoding),
+ static_cast<common::ColumnCategory>(cur_schema.column_category)));
+ }
+
+ // There is no need to free table_schema.
+ storage::TableSchema *table_schema =
+ new storage::TableSchema(schema->table_name, column_schemas);
+ *err_code = common::E_OK;
+ return new storage::TsFileTableWriter(
+ static_cast<storage::WriteFile *>(file), table_schema);
+}
+
+TsFileReader tsfile_reader_new(const char *pathname, ERRNO *err_code) {
+ init_tsfile_config();
+ auto reader = new storage::TsFileReader();
+ int ret = reader->open(pathname);
+ if (ret != common::E_OK) {
+ *err_code = ret;
+ delete reader;
+ return nullptr;
}
- auto *tablet = new storage::Tablet(device_id, &measurement_list,
- &data_type_list, max_rows);
- return tablet;
+ return reader;
+}
+
+ERRNO tsfile_writer_close(TsFileWriter writer) {
+ auto *w = static_cast<storage::TsFileTableWriter *>(writer);
+ int ret = w->flush();
+ if (ret != common::E_OK) {
+ return ret;
+ }
+ ret = w->close();
+ if (ret != common::E_OK) {
+ return ret;
+ }
+ delete w;
+ return ret;
}
-Tablet tablet_new(const char **column_name_list, TSDataType *data_types,
- uint32_t column_num) {
+ERRNO tsfile_reader_close(TsFileReader reader) {
+ auto *ts_reader = static_cast<storage::TsFileReader *>(reader);
+ delete ts_reader;
+ return common::E_OK;
+}
+
+Tablet tablet_new(char **column_name_list, TSDataType *data_types,
+ uint32_t column_num, uint32_t max_rows) {
std::vector<std::string> measurement_list;
std::vector<common::TSDataType> data_type_list;
for (uint32_t i = 0; i < column_num; i++) {
@@ -52,8 +125,7 @@ Tablet tablet_new(const char **column_name_list, TSDataType
*data_types,
data_type_list.push_back(
static_cast<common::TSDataType>(*(data_types + i)));
}
- auto *tablet = new storage::Tablet("", &measurement_list, &data_type_list);
- return tablet;
+ return new storage::Tablet(measurement_list, data_type_list, max_rows);
}
uint32_t tablet_get_cur_row_size(Tablet tablet) {
@@ -61,7 +133,7 @@ uint32_t tablet_get_cur_row_size(Tablet tablet) {
}
ERRNO tablet_add_timestamp(Tablet tablet, uint32_t row_index,
- timestamp timestamp) {
+ Timestamp timestamp) {
return static_cast<storage::Tablet *>(tablet)->add_timestamp(row_index,
timestamp);
}
@@ -69,57 +141,62 @@ ERRNO tablet_add_timestamp(Tablet tablet, uint32_t
row_index,
#define TABLET_ADD_VALUE_BY_NAME_DEF(type) \
ERRNO tablet_add_value_by_name_##type(Tablet tablet, uint32_t row_index, \
const char *column_name, \
- type value) { \
+ const type value) { \
return static_cast<storage::Tablet *>(tablet)->add_value( \
row_index, column_name, value); \
}
-
TABLET_ADD_VALUE_BY_NAME_DEF(int32_t);
TABLET_ADD_VALUE_BY_NAME_DEF(int64_t);
TABLET_ADD_VALUE_BY_NAME_DEF(float);
TABLET_ADD_VALUE_BY_NAME_DEF(double);
TABLET_ADD_VALUE_BY_NAME_DEF(bool);
+ERRNO tablet_add_value_by_name_string(Tablet tablet, uint32_t row_index,
+ const char *column_name,
+ const char *value) {
+ return static_cast<storage::Tablet *>(tablet)->add_value(
+ row_index, column_name, common::String(value));
+}
+
#define TABLE_ADD_VALUE_BY_INDEX_DEF(type) \
ERRNO tablet_add_value_by_index_##type(Tablet tablet, uint32_t row_index, \
uint32_t column_index, \
- type value) { \
+ const type value) { \
return static_cast<storage::Tablet *>(tablet)->add_value( \
row_index, column_index, value); \
}
+ERRNO tablet_add_value_by_index_string(Tablet tablet, uint32_t row_index,
+ uint32_t column_index,
+ const char *value) {
+ return static_cast<storage::Tablet *>(tablet)->add_value(
+ row_index, column_index, common::String(value));
+}
+
TABLE_ADD_VALUE_BY_INDEX_DEF(int32_t);
TABLE_ADD_VALUE_BY_INDEX_DEF(int64_t);
TABLE_ADD_VALUE_BY_INDEX_DEF(float);
TABLE_ADD_VALUE_BY_INDEX_DEF(double);
TABLE_ADD_VALUE_BY_INDEX_DEF(bool);
-void *tablet_get_value(Tablet tablet, uint32_t row_index, uint32_t
schema_index,
- TSDataType *type) {
- common::TSDataType data_type;
- void *result = static_cast<storage::Tablet *>(tablet)->get_value(
- row_index, schema_index, data_type);
- *type = static_cast<TSDataType>(data_type);
- return result;
-}
-
+/*
// TsRecord API
-TsRecord ts_record_new(const char *device_id, timestamp timestamp,
- int timeseries_num) {
- auto *record = new storage::TsRecord(timestamp, device_id, timeseries_num);
- return record;
+TsRecord ts_record_new(const char *device_id, Timestamp timestamp,
+ int timeseries_num) {
+auto *record = new storage::TsRecord(timestamp, device_id,
+timeseries_num); return record;
}
#define INSERT_DATA_INTO_TS_RECORD_BY_NAME_DEF(type) \
- ERRNO insert_data_into_ts_record_by_name_##type( \
- TsRecord data, const char *measurement_name, type value) { \
- auto *record = (storage::TsRecord *)data; \
- storage::DataPoint point(measurement_name, value); \
- if (record->points_.size() + 1 > record->points_.capacity()) \
- return common::E_BUF_NOT_ENOUGH; \
- record->points_.push_back(point); \
- return common::E_OK; \
- }
+ERRNO insert_data_into_ts_record_by_name_##type( \
+ TsRecord data, const char *measurement_name, type value) { \
+ auto *record = (storage::TsRecord *)data; \
+ storage::DataPoint point(measurement_name, value); \
+ if (record->points_.size() + 1 > record->points_.capacity()) \
+ return common::E_BUF_NOT_ENOUGH; \
+ record->points_.push_back(point); \
+ return common::E_OK; \
+}
INSERT_DATA_INTO_TS_RECORD_BY_NAME_DEF(int32_t);
INSERT_DATA_INTO_TS_RECORD_BY_NAME_DEF(int64_t);
@@ -127,184 +204,174 @@ INSERT_DATA_INTO_TS_RECORD_BY_NAME_DEF(bool);
INSERT_DATA_INTO_TS_RECORD_BY_NAME_DEF(float);
INSERT_DATA_INTO_TS_RECORD_BY_NAME_DEF(double);
-void init_tsfile_config() {
- if (!is_init) {
- common::init_config_value();
- is_init = true;
- }
-}
-
-TsFileReader tsfile_reader_new(const char *pathname, ERRNO *err_code) {
- init_tsfile_config();
- auto reader = new storage::TsFileReader();
- int ret = reader->open(pathname);
- if (ret != common::E_OK) {
- *err_code = ret;
- delete reader;
- return nullptr;
- }
- return reader;
-}
-
-TsFileWriter tsfile_writer_new(const char *pathname, ERRNO *err_code) {
- init_tsfile_config();
- auto writer = new storage::TsFileWriter();
- int flags = O_WRONLY | O_CREAT | O_TRUNC;
-#ifdef _WIN32
- flags |= O_BINARY;
-#endif
- int ret = writer->open(pathname, flags, 0644);
- if (ret != common::E_OK) {
- delete writer;
- *err_code = ret;
- return nullptr;
- }
- return writer;
-}
-
TsFileWriter tsfile_writer_new_with_conf(const char *pathname,
- const mode_t flag, ERRNO *err_code,
- TsFileConf *conf) {
- init_tsfile_config();
- auto *writer = new storage::TsFileWriter();
- const int ret = writer->open(pathname, O_CREAT | O_RDWR, flag);
- if (ret != common::E_OK) {
- delete writer;
- *err_code = ret;
- return nullptr;
- }
- return writer;
+ const mode_t flag, ERRNO *err_code,
+ TsFileConf *conf) {
+init_tsfile_config();
+auto *writer = new storage::TsFileWriter();
+const int ret = writer->open(pathname, O_CREAT | O_RDWR, flag);
+if (ret != common::E_OK) {
+ delete writer;
+ *err_code = ret;
+ return nullptr;
}
-
-ERRNO tsfile_writer_close(TsFileWriter writer) {
- auto *w = static_cast<storage::TsFileWriter *>(writer);
- int ret = w->close();
- delete w;
- return ret;
+return writer;
}
-ERRNO tsfile_reader_close(TsFileReader reader) {
- auto *ts_reader = static_cast<storage::TsFileReader *>(reader);
- delete ts_reader;
- return common::E_OK;
+ERRNO tsfile_writer_register_table(TsFileWriter writer, TableSchema *schema)
+{
+std::vector<storage::MeasurementSchema *> measurement_schemas;
+std::vector<common::ColumnCategory> column_categories;
+measurement_schemas.resize(schema->column_num);
+for (int i = 0; i < schema->column_num; i++) {
+ ColumnSchema *cur_schema = schema->column_schemas + i;
+ measurement_schemas[i] = new storage::MeasurementSchema(
+ cur_schema->column_name,
+ static_cast<common::TSDataType>(cur_schema->data_type));
+ column_categories.push_back(
+ static_cast<common::ColumnCategory>(cur_schema->column_category));
}
-
-ERRNO tsfile_writer_register_table(TsFileWriter writer, TableSchema *schema) {
- std::vector<storage::MeasurementSchema *> measurement_schemas;
- std::vector<common::ColumnCategory> column_categories;
- measurement_schemas.resize(schema->column_num);
- for (int i = 0; i < schema->column_num; i++) {
- ColumnSchema *cur_schema = schema->column_schemas + i;
- measurement_schemas[i] = new storage::MeasurementSchema(
- cur_schema->column_name,
- static_cast<common::TSDataType>(cur_schema->data_type));
- column_categories.push_back(
- static_cast<common::ColumnCategory>(cur_schema->column_category));
- }
- auto tsfile_writer = static_cast<storage::TsFileWriter *>(writer);
- return
tsfile_writer->register_table(std::make_shared<storage::TableSchema>(
- schema->table_name, measurement_schemas, column_categories));
+auto tsfile_writer = static_cast<storage::TsFileWriter *>(writer);
+return
+tsfile_writer->register_table(std::make_shared<storage::TableSchema>(
+ schema->table_name, measurement_schemas, column_categories));
}
ERRNO tsfile_writer_register_timeseries(TsFileWriter writer,
- const char *device_id,
- const TimeseriesSchema *schema) {
- auto *w = static_cast<storage::TsFileWriter *>(writer);
+ const char *device_id,
+ const TimeseriesSchema *schema) {
+auto *w = static_cast<storage::TsFileWriter *>(writer);
- int ret = w->register_timeseries(
- device_id,
- storage::MeasurementSchema(
- schema->timeseries_name,
- static_cast<common::TSDataType>(schema->data_type),
- static_cast<common::TSEncoding>(schema->encoding),
- static_cast<common::CompressionType>(schema->compression)));
- return ret;
+int ret = w->register_timeseries(
+ device_id,
+ storage::MeasurementSchema(
+ schema->timeseries_name,
+ static_cast<common::TSDataType>(schema->data_type),
+ static_cast<common::TSEncoding>(schema->encoding),
+ static_cast<common::CompressionType>(schema->compression)));
+return ret;
}
ERRNO tsfile_writer_register_device(TsFileWriter writer,
- const device_schema *device_schema) {
- auto *w = static_cast<storage::TsFileWriter *>(writer);
- for (int column_id = 0; column_id < device_schema->timeseries_num;
- column_id++) {
- TimeseriesSchema schema = device_schema->timeseries_schema[column_id];
- const ERRNO ret = w->register_timeseries(
- device_schema->device_name,
- storage::MeasurementSchema(
- schema.timeseries_name,
- static_cast<common::TSDataType>(schema.data_type),
- static_cast<common::TSEncoding>(schema.encoding),
- static_cast<common::CompressionType>(schema.compression)));
- if (ret != common::E_OK) {
- return ret;
- }
+ const device_schema *device_schema) {
+auto *w = static_cast<storage::TsFileWriter *>(writer);
+for (int column_id = 0; column_id < device_schema->timeseries_num;
+ column_id++) {
+ TimeseriesSchema schema =
+ device_schema->timeseries_schema[column_id]; const ERRNO ret =
+ w->register_timeseries(
+ device_schema->device_name,
+ storage::MeasurementSchema(
+ schema.timeseries_name,
+ static_cast<common::TSDataType>(schema.data_type),
+ static_cast<common::TSEncoding>(schema.encoding),
+ static_cast<common::CompressionType>(schema.compression)));
+ if (ret != common::E_OK) {
+ return ret;
}
- return common::E_OK;
+}
+return common::E_OK;
}
ERRNO tsfile_writer_write_ts_record(TsFileWriter writer, TsRecord data) {
- auto *w = static_cast<storage::TsFileWriter *>(writer);
- const storage::TsRecord *record = static_cast<storage::TsRecord *>(data);
- const int ret = w->write_record(*record);
- return ret;
+auto *w = static_cast<storage::TsFileWriter *>(writer);
+const storage::TsRecord *record = static_cast<storage::TsRecord *>(data);
+const int ret = w->write_record(*record);
+return ret;
}
ERRNO tsfile_writer_write_tablet(TsFileWriter writer, Tablet tablet) {
- auto *w = static_cast<storage::TsFileWriter *>(writer);
- const auto *tbl = static_cast<storage::Tablet *>(tablet);
- return w->write_tablet(*tbl);
+auto *w = static_cast<storage::TsFileWriter *>(writer);
+const auto *tbl = static_cast<storage::Tablet *>(tablet);
+return w->write_tablet(*tbl);
}
-
-ERRNO tsfile_writer_flush_data(TsFileWriter writer) {
- auto *w = static_cast<storage::TsFileWriter *>(writer);
- return w->flush();
+*/
+ERRNO tsfile_writer_write(TsFileWriter writer, Tablet tablet) {
+ auto *w = static_cast<storage::TsFileTableWriter *>(writer);
+ auto *tbl = static_cast<storage::Tablet *>(tablet);
+ return w->write_table(*tbl);
}
-// Query
+// ERRNO tsfile_writer_flush_data(TsFileWriter writer) {
+// auto *w = static_cast<storage::TsFileWriter *>(writer);
+// return w->flush();
+// }
-ResultSet tsfile_reader_query_table(TsFileReader reader, const char
*table_name,
-char **columns, uint32_t column_num,
- timestamp start_time, timestamp end_time) {
- // TODO: Implement query table with tsfile reader.
- return nullptr;
-}
+// Query
-ResultSet tsfile_reader_query_device(TsFileReader reader, const char*
device_name,
- char** sensor_name, uint32_t sensor_num,
- timestamp start_time, timestamp end_time) {
+ResultSet tsfile_query_table(TsFileReader reader, const char *table_name,
+ char **columns, uint32_t column_num,
+ Timestamp start_time, Timestamp end_time,
+ ERRNO *err_code) {
auto *r = static_cast<storage::TsFileReader *>(reader);
- std::vector<std::string> selected_paths;
- selected_paths.reserve(sensor_num);
- for (uint32_t i = 0; i < sensor_num; i++) {
- selected_paths.push_back(std::string(device_name) + "." +
std::string(sensor_name[i]));
+ storage::ResultSet *table_result_set = nullptr;
+ std::vector<std::string> column_names;
+ for (uint32_t i = 0; i < column_num; i++) {
+ column_names.emplace_back(columns[i]);
+ }
+ *err_code = r->query(table_name, column_names, start_time, end_time,
+ table_result_set);
+ return table_result_set;
+}
+
+// ResultSet tsfile_reader_query_device(TsFileReader reader,
+// const char *device_name,
+// char **sensor_name, uint32_t
sensor_num,
+// Timestamp start_time, Timestamp
+// end_time) {
+// auto *r = static_cast<storage::TsFileReader *>(reader);
+// std::vector<std::string> selected_paths;
+// selected_paths.reserve(sensor_num);
+// for (uint32_t i = 0; i < sensor_num; i++) {
+// selected_paths.push_back(std::string(device_name) + "." +
+// std::string(sensor_name[i]));
+// }
+// storage::ResultSet *qds = nullptr;
+// r->query(selected_paths, start_time, end_time, qds);
+// return qds;
+// }
+
+bool tsfile_result_set_next(ResultSet result_set, ERRNO *err_code) {
+ auto *r = static_cast<storage::TableResultSet *>(result_set);
+ bool has_next = true;
+ int ret = common::E_OK;
+ ret = r->next(has_next);
+ *err_code = ret;
+ if (ret != common::E_OK) {
+ return false;
}
- storage::ResultSet *qds = nullptr;
- r->query(selected_paths, start_time, end_time, qds);
- return qds;
-}
-
-bool tsfile_result_set_has_next(ResultSet result_set) {
- auto *r = static_cast<storage::QDSWithoutTimeGenerator *>(result_set);
- bool has_next = false;
- r->next(has_next);
return has_next;
}
#define TSFILE_RESULT_SET_GET_VALUE_BY_NAME_DEF(type)
\
type tsfile_result_set_get_value_by_name_##type(ResultSet result_set,
\
const char *column_name) {
\
- auto *r = static_cast<storage::ResultSet *>(result_set);
\
+ auto *r = static_cast<storage::TableResultSet *>(result_set);
\
return r->get_value<type>(column_name);
\
}
+
TSFILE_RESULT_SET_GET_VALUE_BY_NAME_DEF(bool);
TSFILE_RESULT_SET_GET_VALUE_BY_NAME_DEF(int32_t);
TSFILE_RESULT_SET_GET_VALUE_BY_NAME_DEF(int64_t);
TSFILE_RESULT_SET_GET_VALUE_BY_NAME_DEF(float);
TSFILE_RESULT_SET_GET_VALUE_BY_NAME_DEF(double);
+char *tsfile_result_set_get_value_by_name_string(ResultSet result_set,
+ const char *column_name) {
+ auto *r = static_cast<storage::TableResultSet *>(result_set);
+ common::String *ret = r->get_value<common::String *>(column_name);
+ // Caller should free return's char* 's space.
+ char *dup = (char *)malloc(ret->len_ + 1);
+ if (dup) {
+ memcpy(dup, ret->buf_, ret->len_);
+ dup[ret->len_] = '\0';
+ }
+ return dup;
+}
#define TSFILE_RESULT_SET_GET_VALUE_BY_INDEX_DEF(type) \
type tsfile_result_set_get_value_by_index_##type(ResultSet result_set, \
uint32_t column_index) { \
- auto *r = static_cast<storage::ResultSet *>(result_set); \
+ auto *r = static_cast<storage::TableResultSet *>(result_set); \
return r->get_value<type>(column_index); \
}
@@ -314,22 +381,40 @@ TSFILE_RESULT_SET_GET_VALUE_BY_INDEX_DEF(float);
TSFILE_RESULT_SET_GET_VALUE_BY_INDEX_DEF(double);
TSFILE_RESULT_SET_GET_VALUE_BY_INDEX_DEF(bool);
+char *tsfile_result_set_get_value_by_index_string(ResultSet result_set,
+ uint32_t column_index) {
+ auto *r = static_cast<storage::TableResultSet *>(result_set);
+ common::String *ret = r->get_value<common::String *>(column_index);
+ // Caller should free return's char* 's space.
+ char *dup = (char *)malloc(ret->len_ + 1);
+ if (dup) {
+ memcpy(dup, ret->buf_, ret->len_);
+ dup[ret->len_] = '\0';
+ }
+ return dup;
+}
+
bool tsfile_result_set_is_null_by_name(ResultSet result_set,
const char *column_name) {
- auto *r = static_cast<storage::ResultSet *>(result_set);
+ auto *r = static_cast<storage::TableResultSet *>(result_set);
return r->is_null(column_name);
}
bool tsfile_result_set_is_null_by_index(const ResultSet result_set,
const uint32_t column_index) {
- auto *r = static_cast<storage::ResultSet *>(result_set);
+ auto *r = static_cast<storage::TableResultSet *>(result_set);
return r->is_null(column_index);
}
ResultSetMetaData tsfile_result_set_get_metadata(ResultSet result_set) {
- auto *r = static_cast<storage::QDSWithoutTimeGenerator *>(result_set);
+ auto *r = static_cast<storage::TableResultSet *>(result_set);
+ if (result_set == NULL) {
+ return ResultSetMetaData();
+ }
+
ResultSetMetaData meta_data;
- std::shared_ptr<storage::ResultSetMetadata> result_set_metadata =
r->get_metadata();
+ std::shared_ptr<storage::ResultSetMetadata> result_set_metadata =
+ r->get_metadata();
meta_data.column_num = result_set_metadata->get_column_count();
meta_data.column_names =
static_cast<char **>(malloc(meta_data.column_num * sizeof(char *)));
@@ -344,73 +429,127 @@ ResultSetMetaData
tsfile_result_set_get_metadata(ResultSet result_set) {
return meta_data;
}
-char *tsfile_result_set_meta_get_column_name(ResultSetMetaData result_set,
- uint32_t column_index) {
+char *tsfile_result_set_metadata_get_column_name(ResultSetMetaData result_set,
+ uint32_t column_index) {
+ if (column_index >= result_set.column_num) {
+ return nullptr;
+ }
return result_set.column_names[column_index];
}
-TSDataType tsfile_result_set_meta_get_data_type(ResultSetMetaData result_set,
- uint32_t column_index) {
+TSDataType tsfile_result_set_metadata_get_data_type(
+ ResultSetMetaData result_set, uint32_t column_index) {
+ if (column_index >= result_set.column_num) {
+ return TS_DATATYPE_INVALID;
+ }
return result_set.data_types[column_index];
}
-int tsfile_result_set_meta_get_column_num(ResultSetMetaData result_set) {
+int tsfile_result_set_metadata_get_column_num(ResultSetMetaData result_set) {
return result_set.column_num;
}
+// TableSchema tsfile_reader_get_table_schema(TsFileReader reader,
+// const char *table_name) {
+// // TODO: Implement get table schema with tsfile reader.
+// return TableSchema();
+// }
+//
+// DeviceSchema tsfile_reader_get_device_schema(TsFileReader reader,
+// const char *device_id) {
+// auto *r = static_cast<storage::TsFileReader *>(reader);
+// std::vector<storage::MeasurementSchema> measurement_schemas;
+// r->get_timeseries_schema(
+// std::make_shared<storage::StringArrayDeviceID>(device_id),
+// measurement_schemas);
+// DeviceSchema schema;
+// schema.device_name = strdup(device_id);
+// schema.timeseries_num = measurement_schemas.size();
+// schema.timeseries_schema = static_cast<TimeseriesSchema *>(
+// malloc(sizeof(TimeseriesSchema) * schema.timeseries_num));
+// for (int i = 0; i < schema.timeseries_num; i++) {
+// schema.timeseries_schema[i].timeseries_name =
+// strdup(measurement_schemas[i].measurement_name_.c_str());
+// schema.timeseries_schema[i].data_type =
+// static_cast<TSDataType>(measurement_schemas[i].data_type_);
+// schema.timeseries_schema[i].compression =
+// static_cast<CompressionType>(
+// measurement_schemas[i].compression_type_);
+// schema.timeseries_schema[i].encoding =
+// static_cast<TSEncoding>(measurement_schemas[i].encoding_);
+// }
+// return schema;
+// }
+
+
TableSchema tsfile_reader_get_table_schema(TsFileReader reader,
const char *table_name) {
- // TODO: Implement get table schema with tsfile reader.
- return TableSchema();
-}
-
-DeviceSchema tsfile_reader_get_device_schema(TsFileReader reader,
- const char *device_id) {
auto *r = static_cast<storage::TsFileReader *>(reader);
- std::vector<storage::MeasurementSchema> measurement_schemas;
- r->get_timeseries_schema(
- std::make_shared<storage::StringArrayDeviceID>(device_id),
- measurement_schemas);
- DeviceSchema schema;
- schema.device_name = strdup(device_id);
- schema.timeseries_num = measurement_schemas.size();
- schema.timeseries_schema = static_cast<TimeseriesSchema *>(
- malloc(sizeof(TimeseriesSchema) * schema.timeseries_num));
- for (int i = 0; i < schema.timeseries_num; i++) {
- schema.timeseries_schema[i].timeseries_name =
- strdup(measurement_schemas[i].measurement_name_.c_str());
- schema.timeseries_schema[i].data_type =
- static_cast<TSDataType>(measurement_schemas[i].data_type_);
- schema.timeseries_schema[i].compression = static_cast<CompressionType>(
- measurement_schemas[i].compression_type_);
- schema.timeseries_schema[i].encoding =
- static_cast<TSEncoding>(measurement_schemas[i].encoding_);
+ auto table_shcema = r->get_table_schema(table_name);
+ TableSchema ret_schema;
+ ret_schema.table_name = strdup(table_shcema->get_table_name().c_str());
+ int column_num = table_shcema->get_columns_num();
+ ret_schema.column_num = column_num;
+ ret_schema.column_schemas =
static_cast<ColumnSchema*>(malloc(sizeof(ColumnSchema) * column_num));
+ for (int i = 0; i < column_num; i++) {
+ auto column_schema = table_shcema->get_measurement_schemas()[i];
+ ret_schema.column_schemas[i].column_name =
strdup(column_schema->measurement_name_.c_str());
+ ret_schema.column_schemas[i].data_type =
static_cast<TSDataType>(column_schema->data_type_);
+ ret_schema.column_schemas[i].compression =
static_cast<CompressionType>(column_schema->compression_type_);
+ ret_schema.column_schemas[i].encoding =
static_cast<TSEncoding>(column_schema->encoding_);
+ ret_schema.column_schemas[i].column_category =
static_cast<ColumnCategory>(table_shcema->get_column_categories()[i]);
}
- return schema;
+ return ret_schema;
}
TableSchema *tsfile_reader_get_all_table_schemas(TsFileReader reader,
- uint32_t *num) {
- // TODO: Implement get all table schemas.
- return nullptr;
+ uint32_t *size) {
+ auto *r = static_cast<storage::TsFileReader *>(reader);
+ auto table_schemas = r->get_all_table_schemas();
+ size_t table_num = table_schemas.size();
+ TableSchema *ret =
+ static_cast<TableSchema *>(malloc(sizeof(TableSchema) * table_num));
+ for (size_t i = 0; i < table_schemas.size(); i++) {
+ ret[i].table_name = strdup(table_schemas[i]->get_table_name().c_str());
+ int column_num = table_schemas[i]->get_columns_num();
+ ret[i].column_num = column_num;
+ ret[i].column_schemas = static_cast<ColumnSchema *>(
+ malloc(column_num * sizeof(ColumnSchema)));
+ auto column_schemas = table_schemas[i]->get_measurement_schemas();
+ for (int j = 0; j < column_num; j++) {
+ ret[i].column_schemas[j].column_name =
+ strdup(column_schemas[j]->measurement_name_.c_str());
+ ret[i].column_schemas[j].data_type =
+ static_cast<TSDataType>(column_schemas[j]->data_type_);
+ ret[i].column_schemas[j].encoding =
+ static_cast<TSEncoding>(column_schemas[j]->encoding_);
+ ret[i].column_schemas[j].compression =
static_cast<CompressionType>(
+ column_schemas[j]->compression_type_);
+ ret[i].column_schemas[j].column_category =
+ static_cast<ColumnCategory>(
+ table_schemas[i]->get_column_categories()[j]);
+ }
+ }
+ *size = table_num;
+ return ret;
}
// delete pointer
-void free_tsfile_ts_record(TsRecord* record) {
+void free_tsfile_ts_record(TsRecord *record) {
if (*record != nullptr) {
delete static_cast<storage::TsRecord *>(*record);
}
*record = nullptr;
}
-void free_tablet(Tablet* tablet) {
+void free_tablet(Tablet *tablet) {
if (*tablet != nullptr) {
delete static_cast<storage::Tablet *>(*tablet);
}
*tablet = nullptr;
}
-void free_tsfile_result_set(ResultSet* result_set) {
+void free_tsfile_result_set(ResultSet *result_set) {
if (*result_set != nullptr) {
delete static_cast<storage::ResultSet *>(*result_set);
}
@@ -442,4 +581,14 @@ void free_table_schema(TableSchema schema) {
}
free(schema.column_schemas);
}
-void free_column_schema(ColumnSchema schema) { free(schema.column_name); }
\ No newline at end of file
+void free_column_schema(ColumnSchema schema) { free(schema.column_name); }
+
+void free_write_file(WriteFile *write_file) {
+ auto f = static_cast<storage::WriteFile *>(*write_file);
+ delete f;
+ *write_file = nullptr;
+}
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/cpp/src/cwrapper/tsfile_cwrapper.h
b/cpp/src/cwrapper/tsfile_cwrapper.h
index 46cdabbc..af1c9c29 100644
--- a/cpp/src/cwrapper/tsfile_cwrapper.h
+++ b/cpp/src/cwrapper/tsfile_cwrapper.h
@@ -19,9 +19,13 @@
#ifndef SRC_CWRAPPER_TSFILE_CWRAPPER_H_
#define SRC_CWRAPPER_TSFILE_CWRAPPER_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
-#include <cstdint>
-#include <iostream>
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/stat.h>
typedef enum {
TS_DATATYPE_BOOLEAN = 0,
@@ -31,6 +35,7 @@ typedef enum {
TS_DATATYPE_DOUBLE = 4,
TS_DATATYPE_TEXT = 5,
TS_DATATYPE_VECTOR = 6,
+ TS_DATATYPE_STRING = 11,
TS_DATATYPE_NULL_TYPE = 254,
TS_DATATYPE_INVALID = 255
} TSDataType;
@@ -67,6 +72,8 @@ typedef enum column_category { TAG = 0, FIELD = 1 }
ColumnCategory;
typedef struct column_schema {
char* column_name;
TSDataType data_type;
+ CompressionType compression;
+ TSEncoding encoding;
ColumnCategory column_category;
} ColumnSchema;
@@ -99,6 +106,8 @@ typedef struct tsfile_conf {
int mem_threshold_kb;
} TsFileConf;
+typedef void* WriteFile;
+
typedef void* TsFileReader;
typedef void* TsFileWriter;
@@ -109,38 +118,148 @@ typedef void* TsRecord;
typedef void* ResultSet;
typedef int32_t ERRNO;
-typedef int64_t timestamp;
+typedef int64_t Timestamp;
-#ifdef __cplusplus
-extern "C" {
-#endif
+/*--------------------------TsFile Reader and Writer------------------------ */
+
+/**
+ * @brief Creates a file for writing.
+ *
+ * @param pathname Target file path to create.
+ * @param err_code [out] E_OK(0), or check error code in errno_define.h.
+ *
+ * @return WriteFile Valid handle on success.
+ *
+ * @note Call free_write_file() to release resources.
+ * @note Before call free_write_file(), make sure TsFileWriter has been closed.
+ */
+
+WriteFile write_file_new(const char* pathname, ERRNO* err_code);
+
+/**
+ * @brief Creates a TsFileWriter for writing a TsFile.
+ *
+ * @param file Target file where the table data will be written.
+ * @param schema Table schema definition.
+ * - Ownership: Should be free it by Caller.
+ * @param err_code [out] E_OK(0), or check error code in errno_define.h.
+ *
+ * @return TsFileWriter Valid handle on success, NULL on failure.
+ *
+ * @note Call tsfile_writer_close() to release resources.
+ */
+TsFileWriter tsfile_writer_new(WriteFile file, TableSchema* schema,
+ ERRNO* err_code);
+
+/**
+ * @brief Creates a TsFileReader for reading a TsFile.
+ *
+ * @param pathname Source TsFiles path. Must be a valid path.
+ * @param err_code E_OK(0), or check error code in errno_define.h.
+ * @return TsFileReader Valid handle on success, NULL on failure.
+ *
+ * @note Call tsfile_reader_close() to release resources.
+ */
+
+TsFileReader tsfile_reader_new(const char* pathname, ERRNO* err_code);
+
+/**
+ * @brief Releases resources associated with a TsFileWriter.
+ *
+ * @param writer [in] Writer handle obtained from tsfile_writer_new().
+ * After call: handle becomes invalid and must not be
reused.
+ * @return ERRNO - E_OK(0) on success, check error code in errno_define.h.
+ */
+ERRNO tsfile_writer_close(TsFileWriter writer);
+
+/**
+ * @brief Releases resources associated with a TsFileReader.
+ *
+ * @param reader [in] Reader handle obtained from tsfile_reader_new().
+ * After call:
+ * Handle becomes invalid and must not be reused.
+ * Result_set obtained by this handle becomes invalid.
+ * @return ERRNO - E_OK(0) on success, or check error code in errno_define.h.
+ */
+ERRNO tsfile_reader_close(TsFileReader reader);
/*--------------------------Tablet API------------------------ */
-Tablet tablet_new_with_device(const char* device_id, char** column_name_list,
- TSDataType* data_types, int column_num,
- int max_rows);
-Tablet tablet_new(const char** column_name_list, TSDataType* data_types,
- int column_num);
+/**
+ * @brief Creates a Tablet for batch data.
+ *
+ * @param column_name_list [in] Column names array. Size=column_num.
+ * @param data_types [in] Data types array. Size=column_num.
+ * @param column_num [in] Number of columns. Must be ≥1.
+ * @param max_rows [in] Pre-allocated row capacity. Must be ≥1.
+ * @return Tablet Valid handle.
+ * @note Call free_tablet() to release resources.
+ */
+Tablet tablet_new(char** column_name_list, TSDataType* data_types,
+ uint32_t column_num, uint32_t max_rows);
+/**
+ * @brief Gets current row count in the Tablet.
+ *
+ * @param tablet [in] Valid Tablet handle.
+ * @return uint32_t Row count (0 to max_rows-1).
+ */
uint32_t tablet_get_cur_row_size(Tablet tablet);
+/**
+ * @brief Assigns timestamp to a row in the Tablet.
+ *
+ * @param tablet [in] Valid Tablet handle.
+ * @param row_index [in] Target row (0 ≤ index < max_rows).
+ * @param timestamp [in] Timestamp with int64_t type.
+ * @return ERRNO - E_OK(0)/E_OUT_OF_RANGE(5) or check errno_define.h.
+ */
ERRNO tablet_add_timestamp(Tablet tablet, uint32_t row_index,
- timestamp timestamp);
-
-#define TABLET_ADD_VALUE_BY_NAME(type) \
- ERRNO tablet_add_value_by_name_##type(Tablet* tablet, uint32_t row_index, \
- char* column_name, type value);
+ Timestamp timestamp);
+/**
+ * @brief Adds a value to a Tablet row by column name (generic types).
+ *
+ * @param tablet [in] Valid Tablet handle.
+ * @param row_index [in] Target row (0 ≤ index < max_rows).
+ * @param column_name [in] Existing column name from Tablet schema.
+ * @param value [in] Value to add. Type must match column schema.
+ * @return ERRNO - E_OK(0) or check errno_define.h.
+ *
+ * @note Generated for types: int32_t, int64_t, float, double, bool
+ */
+#define TABLET_ADD_VALUE_BY_NAME(type) \
+ ERRNO tablet_add_value_by_name_##type(Tablet tablet, uint32_t row_index, \
+ const char* column_name, \
+ const type value);
TABLET_ADD_VALUE_BY_NAME(int32_t);
TABLET_ADD_VALUE_BY_NAME(int64_t);
TABLET_ADD_VALUE_BY_NAME(float);
TABLET_ADD_VALUE_BY_NAME(double);
TABLET_ADD_VALUE_BY_NAME(bool);
+/**
+ * @brief Adds a string value to a Tablet row by column name.
+ *
+ * @param value [in] Null-terminated string. Ownership remains with caller.
+ * @return ERRNO.
+ */
+ERRNO tablet_add_value_by_name_string(Tablet tablet, uint32_t row_index,
+ const char* column_name,
+ const char* value);
+
+/**
+ * @brief Adds a value to a Tablet row by column index (generic types).
+ *
+ * @param column_index [in] Column position (0 ≤ index < column_num).
+ * @return ERRNO - E_OK(0) or check errno_define.h.
+ *
+ * @note Generated for types: int32_t, int64_t, float, double, bool
+ */
#define TABLE_ADD_VALUE_BY_INDEX(type) \
ERRNO tablet_add_value_by_index_##type(Tablet tablet, uint32_t row_index, \
- uint32_t column_index, type value);
+ uint32_t column_index, \
+ const type value);
TABLE_ADD_VALUE_BY_INDEX(int32_t);
TABLE_ADD_VALUE_BY_INDEX(int64_t);
@@ -148,55 +267,98 @@ TABLE_ADD_VALUE_BY_INDEX(float);
TABLE_ADD_VALUE_BY_INDEX(double);
TABLE_ADD_VALUE_BY_INDEX(bool);
-void* tablet_get_value(Tablet tablet, uint32_t row_index, uint32_t
schema_index,
- TSDataType* type);
+/**
+ * @brief Adds a string value to a Tablet row by column index.
+ *
+ * @param value [in] Null-terminated string. Copied internally.
+ */
+ERRNO tablet_add_value_by_index_string(Tablet tablet, uint32_t row_index,
+ uint32_t column_index,
+ const char* value);
/*--------------------------TsRecord API------------------------ */
-TsRecord ts_record_new(const char* device_id, timestamp timestamp,
- int timeseries_num);
+/*
+TsRecord ts_record_new(const char* device_id, Timestamp timestamp,
+ int timeseries_num);
#define INSERT_DATA_INTO_TS_RECORD_BY_NAME(type) \
- ERRNO insert_data_into_ts_record_by_name_##type( \
- TsRecord data, const char* measurement_name, type value);
+ ERRNO insert_data_into_ts_record_by_name_##type( \
+ TsRecord data, const char* measurement_name, type value);
INSERT_DATA_INTO_TS_RECORD_BY_NAME(int32_t);
INSERT_DATA_INTO_TS_RECORD_BY_NAME(int64_t);
INSERT_DATA_INTO_TS_RECORD_BY_NAME(bool);
INSERT_DATA_INTO_TS_RECORD_BY_NAME(float);
INSERT_DATA_INTO_TS_RECORD_BY_NAME(double);
-
-/*--------------------------TsFile Reader and Writer------------------------ */
-TsFileReader tsfile_reader_new(const char* pathname, ERRNO* err_code);
-TsFileWriter tsfile_writer_new(const char* pathname, ERRNO* err_code);
-TsFileWriter tsfile_writer_new_with_conf(const char* pathname, mode_t flag,
- ERRNO* err_code, TsFileConf* conf);
-
-ERRNO tsfile_writer_close(TsFileWriter writer);
-ERRNO tsfile_reader_close(TsFileReader reader);
+/*
/*--------------------------TsFile Writer Register------------------------ */
+/*
ERRNO tsfile_writer_register_table(TsFileWriter writer, TableSchema* schema);
ERRNO tsfile_writer_register_timeseries(TsFileWriter writer,
- const char* device_id,
- const TimeseriesSchema* schema);
+ const char* device_id,
+ const TimeseriesSchema* schema);
ERRNO tsfile_writer_register_device(TsFileWriter writer,
- const DeviceSchema* device_schema);
+ const DeviceSchema* device_schema);
+ */
+
+/*-------------------TsFile Writer write data------------------ */
+
+/**
+ * @brief Writes data from a Tablet to the TsFile.
+ *
+ * @param writer [in] Valid TsFileWriter handle. Must be initialized.
+ * @param tablet [in] Tablet containing data. Should be freed after successful
+ * write.
+ * @return ERRNO - E_OK(0), or check error code in errno_define.h.
+ *
+ */
-/*-------------------TsFile Writer write and flush data------------------ */
-ERRNO tsfile_writer_write_tablet(TsFileWriter writer, Tablet tablet);
-ERRNO tsfile_writer_write_ts_record(TsFileWriter writer, TsRecord record);
-ERRNO tsfile_writer_flush_data(TsFileWriter writer);
+ERRNO tsfile_writer_write(TsFileWriter writer, Tablet tablet);
+// ERRNO tsfile_writer_write_tablet(TsFileWriter writer, Tablet tablet);
+// ERRNO tsfile_writer_write_ts_record(TsFileWriter writer, TsRecord record);
+// ERRNO tsfile_writer_flush_data(TsFileWriter writer);
/*-------------------TsFile reader query data------------------ */
-ResultSet tsfile_reader_query_table(TsFileReader reader, const char*
table_name,
- char** columns, uint32_t column_num,
- timestamp start_time, timestamp end_time);
-ResultSet tsfile_reader_query_device(TsFileReader reader,
- const char* device_name,
- char** sensor_name, uint32_t sensor_num,
- timestamp start_time, timestamp end_time);
-bool tsfile_result_set_has_next(ResultSet result_set);
+/**
+ * @brief Queries time series data from a specific table within time range.
+ *
+ * @param reader [in] Valid TsFileReader handle from tsfile_reader_new().
+ * @param table_name [in] Target table name. Must exist in the TS file.
+ * @param columns [in] Array of column names to fetch.
+ * @param column_num [in] Number of columns in array.
+ * @param start_time [in] Start timestamp.
+ * @param end_time [in] End timestamp. Must ≥ start_time.
+ * @return ResultSet Query results handle. Must be freed with
+ * free_tsfile_result_set().
+ */
+ResultSet tsfile_query_table(TsFileReader reader, const char* table_name,
+ char** columns, uint32_t column_num,
+ Timestamp start_time, Timestamp end_time,
+ ERRNO* err_code);
+// ResultSet tsfile_reader_query_device(TsFileReader reader,
+// const char* device_name,
+// char** sensor_name, uint32_t
sensor_num,
+// Timestamp start_time, Timestamp
+// end_time);
+
+/**
+ * @brief Check and fetch the next row in the ResultSet.
+ *
+ * @param result_set [in] Valid ResultSet handle.
+ * @return bool - true: Row available, false: End of data or error.
+ */
+bool tsfile_result_set_next(ResultSet result_set, ERRNO* error_code);
+
+/**
+ * @brief Gets value from current row by column name (generic types).
+ *
+ * @param result_set [in] Valid ResultSet with active row (after next()=true).
+ * @param column_name [in] Existing column name in result schema.
+ * @return type-value, return type-specific value.
+ * @note Generated for: bool, int32_t, int64_t, float, double
+ */
#define TSFILE_RESULT_SET_GET_VALUE_BY_NAME(type) \
type tsfile_result_set_get_value_by_name_##type(ResultSet result_set, \
const char* column_name)
@@ -206,6 +368,24 @@ TSFILE_RESULT_SET_GET_VALUE_BY_NAME(int64_t);
TSFILE_RESULT_SET_GET_VALUE_BY_NAME(float);
TSFILE_RESULT_SET_GET_VALUE_BY_NAME(double);
+/**
+ * @brief Gets string value from current row by column name.
+ *
+ * @return char* - String pointer. Caller must free this ptr after usage.
+ */
+char* tsfile_result_set_get_value_by_name_string(ResultSet result_set,
+ const char* column_name);
+
+/**
+ * @brief Gets value from current row by column_index[0 <= column_index <<
+ * column_num] (generic types).
+ *
+ * @param result_set [in] Valid ResultSet with active row (after next()=true).
+ * @param column_name [in] Existing column index in result schema.
+ * @return type-value, return type-specific value.
+ * @note Generated for: bool, int32_t, int64_t, float, double
+ */
+
#define TSFILE_RESULT_SET_GET_VALUE_BY_INDEX(type) \
type tsfile_result_set_get_value_by_index_##type(ResultSet result_set, \
uint32_t column_index);
@@ -216,27 +396,90 @@ TSFILE_RESULT_SET_GET_VALUE_BY_INDEX(float);
TSFILE_RESULT_SET_GET_VALUE_BY_INDEX(double);
TSFILE_RESULT_SET_GET_VALUE_BY_INDEX(bool);
+/**
+ * @brief Gets string value from current row by column index.
+ *
+ * @return char* - String pointer. Caller must free this ptr after usage.
+ */
+char* tsfile_result_set_get_value_by_index_string(ResultSet result_set,
+ uint32_t column_index);
+
+/**
+ * @brief Checks if the current row's column value is NULL by column name.
+ *
+ * @param result_set [in] Valid ResultSet with active row (after next()=true).
+ * @param column_name [in] Existing column name in result schema.
+ * @return bool - true: Value is NULL or column not found, false: Valid value.
+ */
bool tsfile_result_set_is_null_by_name(ResultSet result_set,
const char* column_name);
+/**
+ * @brief Checks if the current row's column value is NULL by column index.
+ *
+ * @param column_index [in] Column position (0 ≤ index < result_column_count).
+ * @return bool - true: Value is NULL or index out of range, false: Valid
value.
+ */
bool tsfile_result_set_is_null_by_index(ResultSet result_set,
uint32_t column_index);
+/*-------------------TsFile reader query metadata------------------ */
+
+/**
+ * @brief Retrieves metadata describing the ResultSet's schema.
+ *
+ * @param result_set [in] Valid ResultSet handle.
+ * @return ResultSetMetaData Metadata handle. Caller should free the
+ * ResultSetMataData after usage.
+ * @note Before calling this func, check if result_set is NULL, which means
+ * the query may be not correct.
+ */
ResultSetMetaData tsfile_result_set_get_metadata(ResultSet result_set);
-char* tsfile_result_set_meta_get_column_name(ResultSetMetaData result_set,
- uint32_t column_index);
-TSDataType tsfile_result_set_meta_get_data_type(ResultSetMetaData result_set,
- uint32_t column_index);
-int tsfile_result_set_meta_get_column_num(ResultSetMetaData result_set);
+
+/**
+ * @brief Gets column name by index from metadata.
+ *
+ * @param column_index [in] Column position (0 ≤ index < column_num).
+ * @return const char* Read-only string. NULL if index invalid.
+ */
+char* tsfile_result_set_metadata_get_column_name(ResultSetMetaData result_set,
+ uint32_t column_index);
+
+/**
+ * @brief Gets column data type by index from metadata.
+ *
+ * @return TSDataType Returns TS_DATATYPE_INVALID(255) if index invalid.
+ */
+TSDataType tsfile_result_set_metadata_get_data_type(
+ ResultSetMetaData result_set, uint32_t column_index);
+
+/**
+ * @brief Gets total number of columns in the result schema.
+ *
+ * @return column num in result set metadata.
+ */
+int tsfile_result_set_metadata_get_column_num(ResultSetMetaData result_set);
// Desc table schema.
-TableSchema tsfile_reader_get_table_schema(TsFileReader reader,
- const char* table_name);
-DeviceSchema tsfile_reader_get_device_schema(TsFileReader reader,
- const char* device_id);
+// DeviceSchema tsfile_reader_get_device_schema(TsFileReader reader,
+// const char* device_id);
+/**
+ * @brief Gets specific table's schema in the tsfile.
+ *
+ * @return TableSchema, contains table and column info.
+ * @note Caller should call free_table_schema to free the tableschema.
+ */
+TableSchema tsfile_reader_get_table_schema(TsFileReader reader,
+ const char* table_name);
+/**
+ * @brief Gets all table schema in the tsfile.
+ *
+ * @return TableSchema, contains table and column info.
+ * @note Caller should call free_table_schema and free to free the ptr.
+ */
TableSchema* tsfile_reader_get_all_table_schemas(TsFileReader reader,
- uint32_t* schema_num);
+ uint32_t* size);
// Close and free resource.
void free_tsfile_ts_record(TsRecord* record);
@@ -247,6 +490,7 @@ void free_device_schema(DeviceSchema schema);
void free_timeseries_schema(TimeseriesSchema schema);
void free_table_schema(TableSchema schema);
void free_column_schema(ColumnSchema schema);
+void free_write_file(WriteFile* write_file);
#ifdef __cplusplus
}
diff --git a/cpp/src/reader/block/single_device_tsblock_reader.cc
b/cpp/src/reader/block/single_device_tsblock_reader.cc
index ecda84e2..7c39a416 100644
--- a/cpp/src/reader/block/single_device_tsblock_reader.cc
+++ b/cpp/src/reader/block/single_device_tsblock_reader.cc
@@ -191,8 +191,9 @@ int SingleDeviceTsBlockReader::fill_ids() {
common::String device_id(
device_query_task_->get_device_id()->get_segments().at(
id_column_context.pos_in_device_id_));
- if (RET_FAIL(col_appenders_[pos + 1]->fill((char*)&device_id,
sizeof(device_id),
- current_block_->get_row_count()))) {
+ if (RET_FAIL(col_appenders_[pos + 1]->fill(
+ (char*)&device_id, sizeof(device_id),
+ current_block_->get_row_count()))) {
return ret;
}
}
@@ -234,7 +235,7 @@ void SingleDeviceTsBlockReader::construct_column_context(
const ITimeseriesIndex* time_series_index, Filter* time_filter) {
if (time_series_index == nullptr ||
(time_series_index->get_data_type() != common::TSDataType::VECTOR &&
- time_series_index->get_chunk_meta_list()->empty())) {
+ time_series_index->get_chunk_meta_list()->empty())) {
} else if (time_series_index->get_data_type() == common::VECTOR) {
const AlignedTimeseriesIndex* aligned_time_series_index =
dynamic_cast<const AlignedTimeseriesIndex*>(time_series_index);
diff --git a/cpp/src/reader/table_result_set.cc
b/cpp/src/reader/table_result_set.cc
index b0db3f82..6cf6d7e3 100644
--- a/cpp/src/reader/table_result_set.cc
+++ b/cpp/src/reader/table_result_set.cc
@@ -54,6 +54,7 @@ int TableResultSet::next(bool &has_next) {
if (row_iterator_ == nullptr || !row_iterator_->has_next()) {
has_next = false;
}
+
if (has_next && IS_SUCC(ret)) {
uint32_t len = 0;
bool null = false;
diff --git a/cpp/src/utils/db_utils.h b/cpp/src/utils/db_utils.h
index 8f5f5620..508d3a29 100644
--- a/cpp/src/utils/db_utils.h
+++ b/cpp/src/utils/db_utils.h
@@ -281,6 +281,14 @@ struct ColumnSchema {
encoding_(encoding),
column_category_(column_category) {}
+ ColumnSchema(std::string column_name, TSDataType data_type,
+ ColumnCategory column_category = ColumnCategory::FIELD)
+ : column_name_(std::move(column_name)),
+ data_type_(data_type),
+ compression_(get_default_compression_for_type(data_type)),
+ encoding_(get_default_encoding_for_type(data_type)),
+ column_category_(column_category) {}
+
const std::string &get_column_name() const { return column_name_; }
const TSDataType &get_data_type() const { return data_type_; }
const ColumnCategory &get_column_category() const {
diff --git a/cpp/src/writer/tsfile_table_writer.h
b/cpp/src/writer/tsfile_table_writer.h
index 4abe28ca..15b81485 100644
--- a/cpp/src/writer/tsfile_table_writer.h
+++ b/cpp/src/writer/tsfile_table_writer.h
@@ -60,6 +60,7 @@ class TsFileTableWriter {
tsfile_writer_->register_table(table_schema_ptr);
exclusive_table_name_ = table_schema->get_table_name();
}
+
~TsFileTableWriter();
/**
* Registers a table schema with the writer.
diff --git a/cpp/src/writer/tsfile_writer.cc b/cpp/src/writer/tsfile_writer.cc
index 4cf81339..8f88ec03 100644
--- a/cpp/src/writer/tsfile_writer.cc
+++ b/cpp/src/writer/tsfile_writer.cc
@@ -281,6 +281,29 @@ struct MeasurementNamesFromTablet {
}
};
+int TsFileWriter::do_check_and_prepare_tablet(Tablet &tablet) {
+ if (tablet.column_categories_.empty()) {
+ auto &schema_map = io_writer_->get_schema()->table_schema_map_;
+ auto table_schema_it = schema_map.find(tablet.get_table_name());
+ auto table_schema = table_schema_it->second;
+ uint32_t column_cnt = tablet.get_column_count();
+ for (uint32_t i = 0; i < column_cnt; i++) {
+ auto &col_name = tablet.get_column_name(i);
+ int col_index = table_schema->find_column_index(col_name);
+ if (col_index == -1) {
+ return E_COLUMN_NOT_EXIST;
+ }
+ const common::ColumnCategory column_category =
+ table_schema->get_column_categories()[col_index];
+ tablet.column_categories_.emplace_back(column_category);
+ if (column_category == ColumnCategory::TAG) {
+ tablet.id_column_indexes_.push_back(i);
+ }
+ }
+ }
+ return common::E_OK;
+}
+
template <typename MeasurementNamesGetter>
int TsFileWriter::do_check_schema(std::shared_ptr<IDeviceID> device_id,
MeasurementNamesGetter &measurement_names,
@@ -387,8 +410,7 @@ int TsFileWriter::do_check_schema_aligned(
}
int TsFileWriter::do_check_schema_table(
- std::shared_ptr<IDeviceID> device_id,
- Tablet &tablet,
+ std::shared_ptr<IDeviceID> device_id, Tablet &tablet,
storage::TimeChunkWriter *&time_chunk_writer,
common::SimpleVector<storage::ValueChunkWriter *> &value_chunk_writers) {
int ret = E_OK;
@@ -405,7 +427,6 @@ int TsFileWriter::do_check_schema_table(
if (UNLIKELY(dev_it == schemas_.end()) ||
IS_NULL(device_schema = dev_it->second)) {
-
device_schema = new MeasurementSchemaGroup;
device_schema->is_aligned_ = true;
device_schema->time_chunk_writer_ = new TimeChunkWriter();
@@ -413,34 +434,29 @@ int TsFileWriter::do_check_schema_table(
"", g_config_value_.time_encoding_type_,
g_config_value_.time_compress_type_);
- for (uint32_t i = 0; i <
table_schema->get_measurement_schemas().size(); ++i) {
- if (table_schema->get_column_categories().at(i) ==
common::ColumnCategory::FIELD) {
- auto table_column_schema =
table_schema->get_measurement_schemas().at(i);
- auto device_column_schema = new
MeasurementSchema(table_column_schema->measurement_name_,
- table_column_schema->data_type_,
table_column_schema->encoding_,
- table_column_schema->compression_type_);
+ for (uint32_t i = 0; i <
table_schema->get_measurement_schemas().size();
+ ++i) {
+ if (table_schema->get_column_categories().at(i) ==
+ common::ColumnCategory::FIELD) {
+ auto table_column_schema =
+ table_schema->get_measurement_schemas().at(i);
+ auto device_column_schema = new MeasurementSchema(
+ table_column_schema->measurement_name_,
+ table_column_schema->data_type_,
+ table_column_schema->encoding_,
+ table_column_schema->compression_type_);
if (!table_column_schema->props_.empty()) {
device_column_schema->props_ = table_column_schema->props_;
}
-
device_schema->measurement_schema_map_[device_column_schema->measurement_name_]
= device_column_schema;
+ device_schema->measurement_schema_map_
+ [device_column_schema->measurement_name_] =
+ device_column_schema;
}
}
schemas_[device_id] = device_schema;
}
uint32_t column_cnt = tablet.get_column_count();
- if (tablet.column_categories_.empty()) {
- for (uint32_t i = 0; i < column_cnt; i++) {
- auto& col_name = tablet.get_column_name(i);
- int col_index = table_schema->find_column_index(col_name);
- if (col_index == -1) {
- return E_COLUMN_NOT_EXIST;
- }
- const common::ColumnCategory column_category =
table_schema->get_column_categories()[col_index];
- tablet.column_categories_.emplace_back(column_category);
- }
- }
-
time_chunk_writer = device_schema->time_chunk_writer_;
MeasurementSchemaMap &msm = device_schema->measurement_schema_map_;
@@ -495,19 +511,23 @@ int64_t TsFileWriter::calculate_mem_size_for_all_group() {
if (!chunk_group->is_aligned_) {
ChunkWriter *&chunk_writer = m_schema->chunk_writer_;
if (chunk_writer != nullptr) {
- mem_total_size +=
chunk_writer->estimate_max_series_mem_size();
+ mem_total_size +=
+ chunk_writer->estimate_max_series_mem_size();
}
} else {
ValueChunkWriter *&chunk_writer =
m_schema->value_chunk_writer_;
if (chunk_writer != nullptr) {
- mem_total_size +=
chunk_writer->estimate_max_series_mem_size();
+ mem_total_size +=
+ chunk_writer->estimate_max_series_mem_size();
}
}
}
if (chunk_group->is_aligned_) {
- TimeChunkWriter *&time_chunk_writer =
chunk_group->time_chunk_writer_;
+ TimeChunkWriter *&time_chunk_writer =
+ chunk_group->time_chunk_writer_;
if (time_chunk_writer != nullptr) {
- mem_total_size +=
time_chunk_writer->estimate_max_series_mem_size();
+ mem_total_size +=
+ time_chunk_writer->estimate_max_series_mem_size();
}
}
}
@@ -685,9 +705,13 @@ int TsFileWriter::write_table(Tablet &tablet) {
if (io_writer_->get_schema()->table_schema_map_.find(
tablet.insert_target_name_) ==
io_writer_->get_schema()->table_schema_map_.end()) {
- ret = E_DEVICE_NOT_EXIST;
+ ret = E_TABLE_NOT_EXIST;
+ return ret;
+ }
+ if (RET_FAIL(do_check_and_prepare_tablet(tablet))) {
return ret;
}
+
auto device_id_end_index_pairs = split_tablet_by_device(tablet);
int start_idx = 0;
for (auto &device_id_end_index_pair : device_id_end_index_pairs) {
@@ -696,18 +720,20 @@ int TsFileWriter::write_table(Tablet &tablet) {
if (table_aligned_) {
SimpleVector<ValueChunkWriter *> value_chunk_writers;
TimeChunkWriter *time_chunk_writer = nullptr;
- if (RET_FAIL(do_check_schema_table(
- device_id,
- tablet, time_chunk_writer, value_chunk_writers))) {
+ if (RET_FAIL(do_check_schema_table(device_id, tablet,
+ time_chunk_writer,
+ value_chunk_writers))) {
return ret;
- }
+ }
for (uint32_t i = 0; i < tablet.get_cur_row_size(); i++) {
time_chunk_writer->write(tablet.timestamps_[i]);
}
uint32_t field_col_count = 0;
for (uint32_t i = 0; i < tablet.get_column_count(); ++i) {
- if (tablet.column_categories_[i] ==
common::ColumnCategory::FIELD) {
- ValueChunkWriter *value_chunk_writer =
value_chunk_writers[field_col_count];
+ if (tablet.column_categories_[i] ==
+ common::ColumnCategory::FIELD) {
+ ValueChunkWriter *value_chunk_writer =
+ value_chunk_writers[field_col_count];
if (IS_NULL(value_chunk_writer)) {
continue;
}
@@ -719,9 +745,9 @@ int TsFileWriter::write_table(Tablet &tablet) {
MeasurementNamesFromTablet mnames_getter(tablet);
SimpleVector<ChunkWriter *> chunk_writers;
if (RET_FAIL(
- do_check_schema(device_id, mnames_getter, chunk_writers))) {
+ do_check_schema(device_id, mnames_getter, chunk_writers)))
{
return ret;
- }
+ }
ASSERT(chunk_writers.size() == tablet.get_column_count());
for (uint32_t c = 0; c < chunk_writers.size(); c++) {
ChunkWriter *chunk_writer = chunk_writers[c];
@@ -795,8 +821,9 @@ int TsFileWriter::write_column(ChunkWriter *chunk_writer,
const Tablet &tablet,
return ret;
}
-int TsFileWriter::time_write_column(TimeChunkWriter *time_chunk_writer, const
Tablet &tablet, uint32_t start_idx,
- uint32_t end_idx) {
+int TsFileWriter::time_write_column(TimeChunkWriter *time_chunk_writer,
+ const Tablet &tablet, uint32_t start_idx,
+ uint32_t end_idx) {
int64_t *timestamps = tablet.timestamps_;
int ret = E_OK;
if (IS_NULL(time_chunk_writer) || IS_NULL(timestamps)) {
@@ -811,7 +838,8 @@ int TsFileWriter::time_write_column(TimeChunkWriter
*time_chunk_writer, const Ta
}
int TsFileWriter::value_write_column(ValueChunkWriter *value_chunk_writer,
- const Tablet &tablet, int col_idx,
uint32_t start_idx, uint32_t end_idx) {
+ const Tablet &tablet, int col_idx,
+ uint32_t start_idx, uint32_t end_idx) {
int ret = E_OK;
TSDataType data_type = tablet.schema_vec_->at(col_idx).data_type_;
diff --git a/cpp/src/writer/tsfile_writer.h b/cpp/src/writer/tsfile_writer.h
index 67a74c30..3b155dba 100644
--- a/cpp/src/writer/tsfile_writer.h
+++ b/cpp/src/writer/tsfile_writer.h
@@ -110,34 +110,35 @@ class TsFileWriter {
int write_typed_column(storage::ChunkWriter *chunk_writer,
int64_t *timestamps, bool *col_values,
- common::BitMap &col_notnull_bitmap, uint32_t
start_idx,
- uint32_t end_idx);
+ common::BitMap &col_notnull_bitmap,
+ uint32_t start_idx, uint32_t end_idx);
int write_typed_column(storage::ChunkWriter *chunk_writer,
int64_t *timestamps, int32_t *col_values,
- common::BitMap &col_notnull_bitmap, uint32_t
start_idx,
- uint32_t end_idx);
+ common::BitMap &col_notnull_bitmap,
+ uint32_t start_idx, uint32_t end_idx);
int write_typed_column(storage::ChunkWriter *chunk_writer,
int64_t *timestamps, int64_t *col_values,
- common::BitMap &col_notnull_bitmap, uint32_t
start_idx,
- uint32_t end_idx);
+ common::BitMap &col_notnull_bitmap,
+ uint32_t start_idx, uint32_t end_idx);
int write_typed_column(storage::ChunkWriter *chunk_writer,
int64_t *timestamps, float *col_values,
- common::BitMap &col_notnull_bitmap, uint32_t
start_idx,
- uint32_t end_idx);
+ common::BitMap &col_notnull_bitmap,
+ uint32_t start_idx, uint32_t end_idx);
int write_typed_column(storage::ChunkWriter *chunk_writer,
int64_t *timestamps, double *col_values,
- common::BitMap &col_notnull_bitmap, uint32_t
start_idx,
- uint32_t end_idx);
- int write_typed_column(ChunkWriter*chunk_writer, int64_t*timestamps,
- common::String*col_values,
common::BitMap&col_notnull_bitmap,
- uint32_t start_idx,
- uint32_t end_idx);
+ common::BitMap &col_notnull_bitmap,
+ uint32_t start_idx, uint32_t end_idx);
+ int write_typed_column(ChunkWriter *chunk_writer, int64_t *timestamps,
+ common::String *col_values,
+ common::BitMap &col_notnull_bitmap,
+ uint32_t start_idx, uint32_t end_idx);
template <typename MeasurementNamesGetter>
int do_check_schema(
std::shared_ptr<IDeviceID> device_id,
MeasurementNamesGetter &measurement_names,
common::SimpleVector<storage::ChunkWriter *> &chunk_writers);
+
template <typename MeasurementNamesGetter>
int do_check_schema_aligned(
std::shared_ptr<IDeviceID> device_id,
@@ -145,14 +146,17 @@ class TsFileWriter {
storage::TimeChunkWriter *&time_chunk_writer,
common::SimpleVector<storage::ValueChunkWriter *>
&value_chunk_writers);
int do_check_schema_table(
- std::shared_ptr<IDeviceID> device_id,
- Tablet &tablet,
- storage::TimeChunkWriter *&time_chunk_writer,
- common::SimpleVector<storage::ValueChunkWriter *> &value_chunk_writers);
+ std::shared_ptr<IDeviceID> device_id, Tablet &tablet,
+ storage::TimeChunkWriter *&time_chunk_writer,
+ common::SimpleVector<storage::ValueChunkWriter *>
&value_chunk_writers);
+
+ int do_check_and_prepare_tablet(Tablet &tablet);
// std::vector<storage::ChunkWriter*> &chunk_writers);
int write_column(storage::ChunkWriter *chunk_writer, const Tablet &,
- int col_idx, uint32_t start_idx = 0, uint32_t end_idx =
UINT32_MAX);
- int time_write_column(TimeChunkWriter* time_chunk_writer, const Tablet&
tablet, uint32_t start_idx = 0,
+ int col_idx, uint32_t start_idx = 0,
+ uint32_t end_idx = UINT32_MAX);
+ int time_write_column(TimeChunkWriter *time_chunk_writer,
+ const Tablet &tablet, uint32_t start_idx = 0,
uint32_t end_idx = UINT32_MAX);
int register_timeseries(const std::string &device_path,
MeasurementSchema *measurement_schema,
@@ -184,7 +188,11 @@ class TsFileWriter {
int write_typed_column(ValueChunkWriter *value_chunk_writer,
int64_t *timestamps, double *col_values,
common::BitMap &col_notnull_bitmap,
- uint32_t row_count);int
write_typed_column(ValueChunkWriter*value_chunk_writer, int64_t*timestamps,
common::String*col_values, common::BitMap&col_notnull_bitmap, int32_t
row_count);
+ uint32_t row_count);
+ int write_typed_column(ValueChunkWriter *value_chunk_writer,
+ int64_t *timestamps, common::String *col_values,
+ common::BitMap &col_notnull_bitmap,
+ int32_t row_count);
int write_typed_column(ValueChunkWriter *value_chunk_writer,
int64_t *timestamps, float *col_values,
@@ -203,7 +211,8 @@ class TsFileWriter {
int value_write_column(ValueChunkWriter *value_chunk_writer,
const Tablet &tablet, int col_idx,
- uint32_t start_idx = 0, uint32_t end_idx =
UINT32_MAX);
+ uint32_t start_idx = 0,
+ uint32_t end_idx = UINT32_MAX);
};
} // end namespace storage
diff --git a/cpp/test/cwrapper/cwrapper_test.cc
b/cpp/test/cwrapper/cwrapper_test.cc
index 394063a0..224257e2 100644
--- a/cpp/test/cwrapper/cwrapper_test.cc
+++ b/cpp/test/cwrapper/cwrapper_test.cc
@@ -18,130 +18,172 @@
*/
#include <gtest/gtest.h>
#include <unistd.h>
+#include <utils/db_utils.h>
extern "C" {
+#include "cwrapper/errno_define.h"
#include "cwrapper/tsfile_cwrapper.h"
}
+#include "common/tablet.h"
#include "utils/errno_define.h"
-using namespace common;
-
namespace cwrapper {
class CWrapperTest : public testing::Test {};
-TEST_F(CWrapperTest, RegisterTimeSeries) {
- ERRNO code = 0;
- char* temperature = strdup("temperature");
- TimeseriesSchema ts_schema{temperature, TS_DATATYPE_INT32,
- TS_ENCODING_PLAIN, TS_COMPRESSION_UNCOMPRESSED};
- remove("cwrapper_register_timeseries.tsfile");
- TsFileWriter writer =
tsfile_writer_new("cwrapper_register_timeseries.tsfile", &code);
- ASSERT_EQ(code, 0);
- code = tsfile_writer_register_timeseries(writer, "device1", &ts_schema);
- ASSERT_EQ(code, 0);
- free(temperature);
- tsfile_writer_close(writer);
-}
+// TEST_F(CWrapperTest, RegisterTimeSeries) {
+// ERRNO code = 0;
+// char* temperature = strdup("temperature");
+// TimeseriesSchema ts_schema{temperature, TS_DATATYPE_INT32,
+// TS_ENCODING_PLAIN,
+// TS_COMPRESSION_UNCOMPRESSED};
+// remove("cwrapper_register_timeseries.tsfile");
+// TsFileWriter writer =
+// tsfile_writer_new("cwrapper_register_timeseries.tsfile", &code);
+// ASSERT_EQ(code, 0);
+// code = tsfile_writer_register_timeseries(writer, "device1", &ts_schema);
+// ASSERT_EQ(code, 0);
+// free(temperature);
+// tsfile_writer_close(writer);
+// }
TEST_F(CWrapperTest, WriterFlushTabletAndReadData) {
ERRNO code = 0;
- const int device_num = 50;
- const int measurement_num = 50;
- DeviceSchema device_schema[50];
+ const int column_num = 10;
remove("cwrapper_write_flush_and_read.tsfile");
- TsFileWriter writer =
tsfile_writer_new("cwrapper_write_flush_and_read.tsfile", &code);
- ASSERT_EQ(code, 0);
- for (int i = 0; i < device_num; i++) {
- char* device_name = strdup(("device" + std::to_string(i)).c_str());
- device_schema[i].device_name = device_name;
- device_schema[i].timeseries_num = measurement_num;
- device_schema[i].timeseries_schema = (TimeseriesSchema*)malloc(
- sizeof(TimeseriesSchema) * measurement_num);
- for (int j = 0; j < measurement_num; j++) {
- TimeseriesSchema* schema = device_schema[i].timeseries_schema + j;
- schema->timeseries_name =
- strdup(("measurement" + std::to_string(j)).c_str());
- schema->compression = TS_COMPRESSION_UNCOMPRESSED;
- schema->data_type = TS_DATATYPE_INT64;
- schema->encoding = TS_ENCODING_PLAIN;
- }
- code = tsfile_writer_register_device(writer, &device_schema[i]);
- ASSERT_EQ(code, 0);
- free_device_schema(device_schema[i]);
+ TableSchema schema;
+ schema.table_name = strdup("testtable0");
+ int id_schema_num = 5;
+ int field_schema_num = 5;
+ schema.column_num = column_num;
+ schema.column_schemas =
+ static_cast<ColumnSchema*>(malloc(column_num * sizeof(ColumnSchema)));
+ for (int i = 0; i < id_schema_num; i++) {
+ schema.column_schemas[i] =
+ ColumnSchema{strdup(std::string("id" + std::to_string(i)).c_str()),
+ TS_DATATYPE_STRING, TS_COMPRESSION_UNCOMPRESSED,
+ TS_ENCODING_PLAIN, TAG};
}
- int max_rows = 100;
- for (int i = 0; i < device_num; i++) {
- char* device_name = strdup(("device" + std::to_string(i)).c_str());
- char** measurements_name =
- static_cast<char**>(malloc(measurement_num * sizeof(char*)));
- TSDataType* data_types = static_cast<TSDataType*>(
- malloc(sizeof(TSDataType) * measurement_num));
- for (int j = 0; j < measurement_num; j++) {
- measurements_name[j] =
- strdup(("measurement" + std::to_string(j)).c_str());
- data_types[j] = TS_DATATYPE_INT64;
- }
- Tablet tablet =
- tablet_new_with_device(device_name, measurements_name, data_types,
- measurement_num, max_rows);
- free(device_name);
- free(data_types);
- for (int j = 0; j < measurement_num; j++) {
- free(measurements_name[j]);
- }
- free(measurements_name);
- for (int j = 0; j < measurement_num; j++) {
- for (int row = 0; row < max_rows; row++) {
- tablet_add_timestamp(tablet, row, 16225600 + row);
- }
- for (int row = 0; row < max_rows; row++) {
- tablet_add_value_by_index_int64_t(
- tablet, row, j, static_cast<int64_t>(row + j));
+ for (int i = 0; i < field_schema_num; i++) {
+ schema.column_schemas[i + id_schema_num] =
+ ColumnSchema{strdup(std::string("s" + std::to_string(i)).c_str()),
+ TS_DATATYPE_INT64, TS_COMPRESSION_UNCOMPRESSED,
+ TS_ENCODING_PLAIN, FIELD};
+ }
+ WriteFile file =
+ write_file_new("cwrapper_write_flush_and_read.tsfile", &code);
+ TsFileWriter writer = tsfile_writer_new(file, &schema, &code);
+ ASSERT_EQ(code, RET_OK);
+
+ char** column_names =
+ static_cast<char**>(malloc(column_num * sizeof(char*)));
+ TSDataType* data_types =
+ static_cast<TSDataType*>(malloc(sizeof(TSDataType) * column_num));
+ for (int i = 0; i < id_schema_num; i++) {
+ column_names[i] = strdup(std::string("id" +
std::to_string(i)).c_str());
+ data_types[i] = TS_DATATYPE_STRING;
+ }
+
+ for (int i = 0; i < field_schema_num; i++) {
+ column_names[i + id_schema_num] =
+ strdup(std::string("s" + std::to_string(i)).c_str());
+ data_types[i + id_schema_num] = TS_DATATYPE_INT64;
+ }
+
+ Tablet tablet = tablet_new(column_names, data_types, column_num, 10);
+
+ int num_timestamp = 10;
+ char* literal = new char[std::strlen("device_id") + 1];
+ std::strcpy(literal, "device_id");
+
+ for (int l = 0; l < num_timestamp; l++) {
+ tablet_add_timestamp(tablet, l, l);
+ for (int i = 0; i < schema.column_num; i++) {
+ switch (schema.column_schemas[i].data_type) {
+ case TS_DATATYPE_STRING:
+ tablet_add_value_by_name_string(
+ tablet, l, schema.column_schemas[i].column_name,
+ literal);
+ break;
+ case TS_DATATYPE_INT64:
+ tablet_add_value_by_name_int64_t(
+ tablet, l, schema.column_schemas[i].column_name, l);
+ break;
+ default:
+ break;
}
}
- code = tsfile_writer_write_tablet(writer, tablet);
- ASSERT_EQ(code, 0);
- free_tablet(&tablet);
}
- ASSERT_EQ(tsfile_writer_flush_data(writer), 0);
+ delete[] literal;
+ code = tsfile_writer_write(writer, tablet);
+ ASSERT_EQ(code, RET_OK);
ASSERT_EQ(tsfile_writer_close(writer), 0);
- TsFileReader reader =
tsfile_reader_new("cwrapper_write_flush_and_read.tsfile", &code);
+
+ TsFileReader reader =
+ tsfile_reader_new("cwrapper_write_flush_and_read.tsfile", &code);
ASSERT_EQ(code, 0);
+ ResultSet result_set = tsfile_query_table(reader, schema.table_name,
+ column_names, 10, 0, 100, &code);
- char** sensor_list =
- static_cast<char**>(malloc(measurement_num * sizeof(char*)));
- for (int i = 0; i < measurement_num; i++) {
- sensor_list[i] = strdup(("measurement" + std::to_string(i)).c_str());
+ int row = 0;
+ while (tsfile_result_set_next(result_set, &code) && code == RET_OK) {
+ for (int i = 0; i < schema.column_num; i++) {
+ char* ret = nullptr;
+ switch (schema.column_schemas[i].data_type) {
+ case TS_DATATYPE_STRING:
+ ret = tsfile_result_set_get_value_by_name_string(
+ result_set, schema.column_schemas[i].column_name);
+ ASSERT_EQ(std::string("device_id"), std::string(ret));
+ free(ret);
+ break;
+ case TS_DATATYPE_INT64:
+ ASSERT_EQ(row, tsfile_result_set_get_value_by_name_int64_t(
+ result_set,
+ schema.column_schemas[i].column_name));
+ break;
+ default:
+ break;
+ }
+ }
+ for (int i = 7; i <= 11; i++) {
+ ASSERT_EQ(row, tsfile_result_set_get_value_by_index_int64_t(
+ result_set, i));
+ }
+ row++;
}
- ResultSet result_set =
- tsfile_reader_query_device(reader,"device0", sensor_list,
measurement_num, 16225600,
- 16225600 + max_rows - 1);
-
- ResultSetMetaData metadata = tsfile_result_set_get_metadata(result_set);
- ASSERT_EQ(metadata.column_num, measurement_num);
- ASSERT_EQ(std::string(metadata.column_names[4]),
- std::string("device0.measurement4"));
- ASSERT_EQ(metadata.data_types[9], TS_DATATYPE_INT64);
- for (int i = 0; i < measurement_num - 1; i++) {
- ASSERT_TRUE(tsfile_result_set_has_next(result_set));
- ASSERT_FALSE(tsfile_result_set_is_null_by_index(result_set, i));
- ASSERT_EQ(tsfile_result_set_get_value_by_index_int64_t(result_set, i +
1),
- i * 2);
- ASSERT_EQ(tsfile_result_set_get_value_by_name_int64_t(
- result_set,
- std::string("measurement" + std::to_string(i)).c_str()),
- i * 2);
+ ASSERT_EQ(row, num_timestamp);
+ uint32_t size;
+ TableSchema* all_schema =
+ tsfile_reader_get_all_table_schemas(reader, &size);
+ ASSERT_EQ(1, size);
+ ASSERT_EQ(std::string(all_schema[0].table_name),
+ std::string(schema.table_name));
+ ASSERT_EQ(all_schema[0].column_num, schema.column_num);
+ int count_int64_t = 0;
+ int count_string = 0;
+ for (int i = 0; i < column_num; i++) {
+ if (all_schema[0].column_schemas[i].data_type == TS_DATATYPE_INT64) {
+ count_int64_t++;
+ } else if (all_schema[0].column_schemas[i].data_type ==
+ TS_DATATYPE_STRING) {
+ count_string++;
+ }
}
+
+ ASSERT_EQ(5, count_int64_t);
+ ASSERT_EQ(5, count_string);
+ free_tablet(&tablet);
+ tsfile_reader_close(reader);
free_tsfile_result_set(&result_set);
- free_result_set_meta_data(metadata);
- for (int i = 0; i < measurement_num; i++) {
- free(sensor_list[i]);
+ free_table_schema(schema);
+ free_table_schema(*all_schema);
+ free(all_schema);
+ for (int i = 0; i < column_num; i++) {
+ free(column_names[i]);
}
- free(sensor_list);
- tsfile_reader_close(reader);
- // DeviceSchema schema = tsfile_reader_get_device_schema(reader,
- // "device4"); ASSERT_EQ(schema.timeseries_num, 1);
- // ASSERT_EQ(schema.timeseries_schema->name, std::string("measurement4"));
+ free(column_names);
+ free(data_types);
+ free_write_file(&file);
+
}
} // namespace cwrapper
\ No newline at end of file