This is an automated email from the ASF dual-hosted git repository.

colinlee pushed a commit to branch colin_example_c_cpp
in repository https://gitbox.apache.org/repos/asf/tsfile.git

commit 6a0bebba90022c2fcab1fe9b4cb8255b479fc87d
Author: colin <shuoli...@163.com>
AuthorDate: Wed Feb 26 19:03:28 2025 +0800

    fix c
---
 cpp/examples/c_examples/demo_write.c |  29 +-
 cpp/src/common/schema.h              |   4 +
 cpp/src/cwrapper/errno_define.h      |  77 +++++
 cpp/src/cwrapper/tsfile_cwrapper.cc  | 588 +++++++++++++++++++----------------
 cpp/src/cwrapper/tsfile_cwrapper.h   | 322 +++++++++++++++----
 cpp/test/cwrapper/cwrapper_test.cc   | 182 +++++------
 6 files changed, 757 insertions(+), 445 deletions(-)

diff --git a/cpp/examples/c_examples/demo_write.c 
b/cpp/examples/c_examples/demo_write.c
index 69d4476c..292bb6e2 100644
--- a/cpp/examples/c_examples/demo_write.c
+++ b/cpp/examples/c_examples/demo_write.c
@@ -27,31 +27,32 @@
 ERRNO write_tsfile() {
     ERRNO code = 0;
     char* table_name = "table1";
+    TableSchema table_schema = {.table_name = table_name,
+                            .column_schemas = (ColumnSchema[]){
+                                (ColumnSchema){.column_name = "id1",
+                                             .data_type = TS_DATATYPE_TEXT,
+                                             .column_category = TAG},
+                                (ColumnSchema){.column_name = "id2",
+                                             .data_type = TS_DATATYPE_TEXT,
+                                             .column_category = TAG},
+                                (ColumnSchema){.column_name = "s1",
+                                             .data_type = TS_DATATYPE_INT32,
+                                             .column_category = FIELD}}};
 
     // Create tsfile writer with specify path.
-    TsFileWriter writer = tsfile_writer_new("test.tsfile", &code);
+    TsFileWriter writer = tsfile_writer_new("test.tsfile", &table_schema, 
&code);
     HANDLE_ERROR(code);
 
     // Table schema.
-    TableSchema table_schema = {.table_name = table_name,
-                                .column_schemas = (ColumnSchema[]){
-                                    (ColumnSchema){.column_name = "id1",
-                                                 .data_type = TS_DATATYPE_TEXT,
-                                                 .column_category = TAG},
-                                    (ColumnSchema){.column_name = "id2",
-                                                 .data_type = TS_DATATYPE_TEXT,
-                                                 .column_category = TAG},
-                                    (ColumnSchema){.column_name = "s1",
-                                                 .data_type = 
TS_DATATYPE_INT32,
-                                                 .column_category = FIELD}}};
+
 
     // Register a table with tsfile writer.
     code = tsfile_writer_register_table(writer, &table_schema);
     HANDLE_ERROR(code);
 
     // Create tablet to insert data.
-    Tablet tablet = tablet_new_with_device(
-        table_name, (char*[]){"id1", "id2", "s1"},
+    Tablet tablet = tablet_new(
+        (char*[]){"id1", "id2", "s1"},
         (TSDataType[]){TS_DATATYPE_TEXT, TS_DATATYPE_TEXT, TS_DATATYPE_INT32},
         3, 1024);
 
diff --git a/cpp/src/common/schema.h b/cpp/src/common/schema.h
index 15822041..43cefbc8 100644
--- a/cpp/src/common/schema.h
+++ b/cpp/src/common/schema.h
@@ -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/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 50fba728..048b4dfa 100644
--- a/cpp/src/cwrapper/tsfile_cwrapper.cc
+++ b/cpp/src/cwrapper/tsfile_cwrapper.cc
@@ -19,7 +19,9 @@
 
 #include "cwrapper/tsfile_cwrapper.h"
 
+#include <file/write_file.h>
 #include <reader/qds_without_timegenerator.h>
+#include <writer/tsfile_table_writer.h>
 
 #include "common/tablet.h"
 #include "reader/result_set.h"
@@ -32,23 +34,81 @@ extern "C" {
 
 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;
     }
-    auto *tablet = new storage::Tablet(device_id, &measurement_list,
-                                       &data_type_list, max_rows);
-    return tablet;
 }
 
-Tablet tablet_new(const char **column_name_list, TSDataType *data_types,
-                  uint32_t column_num) {
+TsFileWriter tsfile_writer_new(const char *pathname, TableSchema *schema,
+                               ERRNO *err_code) {
+    int ret;
+    init_tsfile_config();
+    int flags = O_WRONLY | 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);
+    if (ret != common::E_OK) {
+        *err_code = ret;
+        return nullptr;
+    }
+
+    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);
+    return new storage::TsFileTableWriter(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;
+    }
+    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;
+}
+
+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++) {
@@ -56,8 +116,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) {
@@ -73,267 +132,228 @@ 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);                                  \
     }
-
-ERRNO tablet_add_value_by_name_string(Tablet tablet, uint32_t row_index,
-                                      const char* column_name, char* value) {
-    return static_cast<storage::Tablet *>(tablet)->add_value(
-        row_index, column_name, common::String(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, char* value) {
+                                       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;
-}
-
-#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;                                         \
-    }
-
-INSERT_DATA_INTO_TS_RECORD_BY_NAME_DEF(int32_t);
-INSERT_DATA_INTO_TS_RECORD_BY_NAME_DEF(int64_t);
-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;
-}
-
-ERRNO tsfile_writer_close(TsFileWriter writer) {
-    auto *w = static_cast<storage::TsFileWriter *>(writer);
-    int ret = w->close();
-    delete w;
-    return ret;
-}
-
-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));
-    }
-    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);
-
-    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;
-        }
-    }
-    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;
-}
-
-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);
-}
-
-ERRNO tsfile_writer_flush_data(TsFileWriter writer) {
-    auto *w = static_cast<storage::TsFileWriter *>(writer);
-    return w->flush();
-}
+//
+// // 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;
+// }
+//
+// #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;                                         \
+//     }
+//
+// INSERT_DATA_INTO_TS_RECORD_BY_NAME_DEF(int32_t);
+// INSERT_DATA_INTO_TS_RECORD_BY_NAME_DEF(int64_t);
+// 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);
+//
+// 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;
+// }
+//
+// 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));
+// }
+//
+// ERRNO tsfile_writer_register_timeseries(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;
+// }
+//
+// 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;
+//         }
+//     }
+//     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;
+// }
+//
+// 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);
+// }
+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);
+}
+
+// ERRNO tsfile_writer_flush_data(TsFileWriter writer) {
+//     auto *w = static_cast<storage::TsFileWriter *>(writer);
+//     return w->flush();
+// }
 
 // Query
 
-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;
-}
-
-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) {
     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 (int i = 0; i < column_num; i++) {
+        column_names.emplace_back(columns[i]);
     }
-    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);
+    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 = false;
-    r->next(has_next);
+    int ret = common::E_OK;
+    ret = r->next(has_next);
+    *err_code = ret;
+    if (ret != common::E_OK) {
+        return false;
+    }
     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::ResultSet *>(result_set);
+    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.
     return strdup(ret->buf_);
 }
-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);
 
 #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);                              \
     }
 
@@ -342,9 +362,10 @@ TSFILE_RESULT_SET_GET_VALUE_BY_INDEX_DEF(int64_t);
 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::ResultSet *>(result_set);
+    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.
     return strdup(ret->buf_);
@@ -352,18 +373,18 @@ char 
*tsfile_result_set_get_value_by_index_string(ResultSet result_set,
 
 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);
     ResultSetMetaData meta_data;
     std::shared_ptr<storage::ResultSetMetadata> result_set_metadata =
         r->get_metadata();
@@ -381,55 +402,88 @@ 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 < 0 || 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 < 0 || 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();
-}
+// 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;
+// }
 
-DeviceSchema tsfile_reader_get_device_schema(TsFileReader reader,
-                                             const char *device_id) {
+TableSchema *tsfile_reader_get_all_table_schemas(TsFileReader reader,
+                                                 uint32_t *size) {
     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_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 i = 0; i < column_num; i++) {
+            ret[i].column_schemas[i].column_name =
+                strdup(column_schemas[i]->measurement_name_.c_str());
+            ret[i].column_schemas[i].data_type =
+                static_cast<TSDataType>(column_schemas[i]->data_type_);
+            ret[i].column_schemas[i].encoding =
+                static_cast<TSEncoding>(column_schemas[i]->encoding_);
+            ret[i].column_schemas[i].compression = 
static_cast<CompressionType>(
+                column_schemas[i]->compression_type_);
+            ret[i].column_schemas[i].column_category =
+                static_cast<ColumnCategory>(
+                    table_schemas[i]->get_column_categories()[i]);
+        }
     }
-    return schema;
-}
-
-TableSchema *tsfile_reader_get_all_table_schemas(TsFileReader reader,
-                                                 uint32_t *num) {
-    // TODO: Implement get all table schemas.
-    return nullptr;
+    *size = table_num;
+    return ret;
 }
 
 // delete pointer
diff --git a/cpp/src/cwrapper/tsfile_cwrapper.h 
b/cpp/src/cwrapper/tsfile_cwrapper.h
index f0e4cdc6..fffb7b59 100644
--- a/cpp/src/cwrapper/tsfile_cwrapper.h
+++ b/cpp/src/cwrapper/tsfile_cwrapper.h
@@ -24,8 +24,8 @@ extern "C" {
 #endif
 
 #include <stdbool.h>
-#include <sys/stat.h>
 #include <stdint.h>
+#include <sys/stat.h>
 
 typedef enum {
     TS_DATATYPE_BOOLEAN = 0,
@@ -72,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;
 
@@ -116,37 +118,131 @@ typedef void* ResultSet;
 typedef int32_t ERRNO;
 typedef int64_t Timestamp;
 
+/*--------------------------TsFile Reader and Writer------------------------ */
+
+/**
+ * @brief Creates a TsFileWriter for writing TsFiles.
+ *
+ * @param pathname     Target TsFile path. Must be a valid path.
+ * @param schema       Table schema definition.
+ *                     - Ownership: Caller must free it after writer creating.
+ * @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(const char* pathname, TableSchema* schema,
+                               ERRNO* err_code);
+
+/**
+ * @brief Creates a TsFileReader for reading TsFiles.
+ *
+ * @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,
-                  uint32_t 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);
 
+/**
+ * @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, type value);
-
+                                          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, char* value);
+                                      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);
@@ -154,58 +250,92 @@ TABLE_ADD_VALUE_BY_INDEX(float);
 TABLE_ADD_VALUE_BY_INDEX(double);
 TABLE_ADD_VALUE_BY_INDEX(bool);
 
+/**
+ * @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, char* value);
-
-void* tablet_get_value(Tablet tablet, uint32_t row_index, uint32_t 
schema_index,
-                       TSDataType* type);
-
-/*--------------------------TsRecord API------------------------ */
-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);
+                                       uint32_t column_index, const char* 
value);
+
+// /*--------------------------TsRecord API------------------------ */
+// 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);
+//
+// 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);
 
-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 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);
+// ERRNO tsfile_writer_register_device(TsFileWriter writer,
+//                                     const DeviceSchema* device_schema);
 
-/*--------------------------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);
+/*-------------------TsFile Writer write data------------------ */
 
-ERRNO tsfile_writer_close(TsFileWriter writer);
-ERRNO tsfile_reader_close(TsFileReader reader);
+/**
+ * @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 Register------------------------ */
-ERRNO tsfile_writer_register_table(TsFileWriter writer, TableSchema* schema);
-ERRNO tsfile_writer_register_timeseries(TsFileWriter writer,
-                                        const char* device_id,
-                                        const TimeseriesSchema* schema);
-ERRNO tsfile_writer_register_device(TsFileWriter writer,
-                                    const DeviceSchema* device_schema);
-
-/*-------------------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);
+// 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)
@@ -215,9 +345,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);
@@ -228,29 +373,76 @@ 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);
+                                                  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.
+ */
 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);
+// TableSchema tsfile_reader_get_table_schema(TsFileReader reader,
+//                                            const char* table_name);
+// DeviceSchema tsfile_reader_get_device_schema(TsFileReader reader,
+//                                              const char* device_id);
 
 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);
diff --git a/cpp/test/cwrapper/cwrapper_test.cc 
b/cpp/test/cwrapper/cwrapper_test.cc
index 394063a0..85429af7 100644
--- a/cpp/test/cwrapper/cwrapper_test.cc
+++ b/cpp/test/cwrapper/cwrapper_test.cc
@@ -19,6 +19,7 @@
 #include <gtest/gtest.h>
 #include <unistd.h>
 extern "C" {
+#include "cwrapper/errno_define.h"
 #include "cwrapper/tsfile_cwrapper.h"
 }
 
@@ -29,119 +30,102 @@ 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 = "table1";
+    schema.column_num = column_num;
+    schema.column_schemas =
+        static_cast<ColumnSchema*>(malloc(column_num * sizeof(ColumnSchema)));
+    schema.column_schemas[0] =
+        ColumnSchema{"id1", TS_DATATYPE_STRING, TS_COMPRESSION_UNCOMPRESSED,
+                     TS_ENCODING_PLAIN, TAG};
+    schema.column_schemas[1] =
+        ColumnSchema{"id2", TS_DATATYPE_STRING, TS_COMPRESSION_UNCOMPRESSED,
+                     TS_ENCODING_PLAIN, TAG};
+    for (int i = 2; i < column_num; i++) {
+        schema.column_schemas[i] = ColumnSchema{
+            strdup(("s" + std::to_string(i)).c_str()), TS_DATATYPE_INT32,
+            TS_COMPRESSION_UNCOMPRESSED, TS_ENCODING_PLAIN, TAG};
+    }
+    TsFileWriter writer = tsfile_writer_new(
+        "cwrapper_write_flush_and_read.tsfile", &schema, &code);
+    ASSERT_EQ(code, RET_OK);
+
+    for (int i = 2; i < column_num; i++) {
+        free(schema.column_schemas[i].column_name);
     }
+    free(schema.column_schemas);
+
+
     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));
-            }
-        }
-        code = tsfile_writer_write_tablet(writer, tablet);
+    char** column_names =
+        static_cast<char**>(malloc(column_num * sizeof(char*)));
+    TSDataType* data_types =
+        static_cast<TSDataType*>(malloc(sizeof(TSDataType) * column_num));
+
+    column_names[0] = strdup(std::string("id1").c_str());
+    column_names[1] = strdup(std::string("id2").c_str());
+    for (int i = 2; i < column_num; i++) {
+        column_names[i] = strdup(("s" + std::to_string(i)).c_str());
+        data_types[i] = TS_DATATYPE_INT32;
+    }
+    data_types[0] = TS_DATATYPE_STRING;
+    data_types[1] = TS_DATATYPE_STRING;
+    Tablet tablet = tablet_new(column_names, data_types, column_num, max_rows);
+
+    for (int i = 0; i < max_rows; i++) {
+        code = tablet_add_timestamp(tablet, i, static_cast<Timestamp>(i * 10));
+        ASSERT_EQ(code, 0);
+        code = tablet_add_value_by_index_string(tablet, i, 0, "device");
         ASSERT_EQ(code, 0);
-        free_tablet(&tablet);
+        code = tablet_add_value_by_index_string(
+            tablet, i, 1, std::string("sensor" + std::to_string(i)).c_str());
+        ASSERT_EQ(code, 0);
+        for (int j = 2; j < column_num; j++) {
+            code = tablet_add_value_by_index_int32_t(
+                tablet, i, j, static_cast<int32_t>(i * 5));
+            ASSERT_EQ(code, 0);
+        }
     }
-    ASSERT_EQ(tsfile_writer_flush_data(writer), 0);
+    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);
 
-    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());
-    }
+    char** sensor_list = static_cast<char**>(malloc(4 * sizeof(char*)));
+    sensor_list[0] = "id1";
+    sensor_list[1] = "id2";
+    sensor_list[2] = "s1";
+    sensor_list[3] = "s2";
     ResultSet result_set =
-        tsfile_reader_query_device(reader,"device0", sensor_list, 
measurement_num, 16225600,
-                                 16225600 + max_rows - 1);
+        tsfile_query_table(reader, "table1", sensor_list, 4, 0, 100);
 
     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);
-    }
-    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(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"));
+    ASSERT_EQ(metadata.column_num, 4);
+    ASSERT_EQ(std::string(metadata.column_names[3]),
+              std::string("s2"));
+    ASSERT_EQ(metadata.data_types[3], TS_DATATYPE_INT32);
 }
 }  // namespace cwrapper
\ No newline at end of file

Reply via email to