diff --git a/example/client-cpp-example/pom.xml b/example/client-cpp-example/pom.xml index ace95bcfd9ad..4832533b9aab 100644 --- a/example/client-cpp-example/pom.xml +++ b/example/client-cpp-example/pom.xml @@ -60,6 +60,10 @@ <sourceFile>${project.basedir}/src/AlignedTimeseriesSessionExample.cpp</sourceFile> <destinationFile>${project.build.directory}/AlignedTimeseriesSessionExample.cpp</destinationFile> </fileSet> + <fileSet> + <sourceFile>${project.basedir}/src/TableModelSessionExample.cpp</sourceFile> + <destinationFile>${project.build.directory}/TableModelSessionExample.cpp</destinationFile> + </fileSet> <fileSet> <sourceFile>${project.basedir}/src/CMakeLists.txt</sourceFile> <destinationFile>${project.build.directory}/CMakeLists.txt</destinationFile> diff --git a/example/client-cpp-example/src/CMakeLists.txt b/example/client-cpp-example/src/CMakeLists.txt index 91d93193e38b..1b902ceaa579 100644 --- a/example/client-cpp-example/src/CMakeLists.txt +++ b/example/client-cpp-example/src/CMakeLists.txt @@ -38,11 +38,14 @@ LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/client/lib) ADD_EXECUTABLE(SessionExample SessionExample.cpp) ADD_EXECUTABLE(AlignedTimeseriesSessionExample AlignedTimeseriesSessionExample.cpp) +ADD_EXECUTABLE(TableModelSessionExample TableModelSessionExample.cpp) IF(MSVC) TARGET_LINK_LIBRARIES(SessionExample iotdb_session "${CMAKE_SOURCE_DIR}/thrift/lib/Release/thriftmd.lib") TARGET_LINK_LIBRARIES(AlignedTimeseriesSessionExample iotdb_session "${CMAKE_SOURCE_DIR}/thrift/lib/Release/thriftmd.lib") + TARGET_LINK_LIBRARIES(TableModelSessionExample iotdb_session "${CMAKE_SOURCE_DIR}/thrift/lib/Release/thriftmd.lib") ELSE() TARGET_LINK_LIBRARIES(SessionExample iotdb_session pthread) TARGET_LINK_LIBRARIES(AlignedTimeseriesSessionExample iotdb_session pthread) + TARGET_LINK_LIBRARIES(TableModelSessionExample iotdb_session pthread) ENDIF() diff --git a/example/client-cpp-example/src/TableModelSessionExample.cpp b/example/client-cpp-example/src/TableModelSessionExample.cpp index d2e76a410178..4e4f9274342a 100644 --- a/example/client-cpp-example/src/TableModelSessionExample.cpp +++ b/example/client-cpp-example/src/TableModelSessionExample.cpp @@ -40,8 +40,8 @@ void insertRelationalTablet() { ColumnCategory::TAG, ColumnCategory::TAG, ColumnCategory::ATTRIBUTE, - ColumnCategory::MEASUREMENT, - ColumnCategory::MEASUREMENT + ColumnCategory::FIELD, + ColumnCategory::FIELD }; Tablet tablet("table1", schemaList, columnTypes, 100); @@ -67,24 +67,43 @@ void insertRelationalTablet() { } } -template<typename T> -inline void Output(vector<T> &columnNames) { - for (auto &name: columnNames) { - cout << name << "\t"; +void Output(unique_ptr<SessionDataSet> &dataSet) { + for (const string &name: dataSet->getColumnNames()) { + cout << name << " "; + } + cout << endl; + while (dataSet->hasNext()) { + cout << dataSet->next()->toString(); + } + cout << endl; +} + +void OutputWithType(unique_ptr<SessionDataSet> &dataSet) { + for (const string &name: dataSet->getColumnNames()) { + cout << name << " "; + } + cout << endl; + for (const string &type: dataSet->getColumnTypeList()) { + cout << type << " "; + } + cout << endl; + while (dataSet->hasNext()) { + cout << dataSet->next()->toString(); } cout << endl; } int main() { try { - session = new TableSessionBuilder() - .host("127.0.0.1") - .rpcPort(6667) - .username("root") - .password("root") - .build(); - - cout << "Create Database db1,db2" << endl; + session = (new TableSessionBuilder()) + ->host("127.0.0.1") + ->rpcPort(6667) + ->username("root") + ->password("root") + ->build(); + + + cout << "[Create Database db1,db2]\n" << endl; try { session->executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS db1"); session->executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS db2"); @@ -92,59 +111,49 @@ int main() { cout << e.what() << endl; } - cout << "Use db1 as database" << endl; + cout << "[Use db1 as database]\n" << endl; try { session->executeNonQueryStatement("USE db1"); } catch (IoTDBException &e) { cout << e.what() << endl; } - cout << "Create Table table1,table2" << endl; + cout << "[Create Table table1,table2]\n" << endl; try { - session->executeNonQueryStatement(" db1.table1(region_id STRING TAG, plant_id STRING TAG, device_id STRING TAG, model STRING ATTRIBUTE, temperature FLOAT FIELD, humidity DOUBLE FIELD) with (TTL=3600000)"); + session->executeNonQueryStatement("create table db1.table1(region_id STRING TAG, plant_id STRING TAG, device_id STRING TAG, model STRING ATTRIBUTE, temperature FLOAT FIELD, humidity DOUBLE FIELD) with (TTL=3600000)"); session->executeNonQueryStatement("create table db2.table2(region_id STRING TAG, plant_id STRING TAG, color STRING ATTRIBUTE, temperature FLOAT FIELD, speed DOUBLE FIELD) with (TTL=6600000)"); } catch (IoTDBException &e) { cout << e.what() << endl; } - cout << "Show Tables" << endl; + cout << "[Show Tables]\n" << endl; try { - SessionDataSet dataSet = session->executeQueryStatement("SHOW TABLES"); - Output(dataSet.getColumnNames()); - while(dataSet.hasNext()) { - Output(dataSet.next()); - } + unique_ptr<SessionDataSet> dataSet = session->executeQueryStatement("SHOW TABLES"); + Output(dataSet); } catch (IoTDBException &e) { cout << e.what() << endl; } - cout << "Show tables from specific database" << endl; + cout << "[Show tables from specific database]\n" << endl; try { - SessionDataSet dataSet = session->executeQueryStatement("SHOW TABLES FROM db1"); - Output(dataSet.getColumnNames()); - while(dataSet.hasNext()) { - Output(dataSet.next()); - } + unique_ptr<SessionDataSet> dataSet = session->executeQueryStatement("SHOW TABLES FROM db1"); + Output(dataSet); } catch (IoTDBException &e) { cout << e.what() << endl; } - cout << "InsertTablet" << endl; + cout << "[InsertTablet]\n" << endl; try { insertRelationalTablet(); } catch (IoTDBException &e) { cout << e.what() << endl; } - cout << "Query Table Data" << endl; + cout << "[Query Table Data]\n" << endl; try { - SessionDataSet dataSet = session->executeQueryStatement("SELECT * FROM table1" + unique_ptr<SessionDataSet> dataSet = session->executeQueryStatement("SELECT * FROM table1" " where region_id = '1' and plant_id in ('3', '5') and device_id = '3'"); - Output(dataSet.getColumnNames()); - Output(dataSet.getColumnTypeList()); - while(dataSet.hasNext()) { - Output(dataSet.next()); - } + OutputWithType(dataSet); } catch (IoTDBException &e) { cout << e.what() << endl; } @@ -152,44 +161,38 @@ int main() { session->close(); // specify database in constructor - session = new TableSessionBuilder() - .host("127.0.0.1") - .rpcPort(6667) - .username("root") - .password("root") - .database("db1") - .build(); - - cout << "Show tables from current database(db1)" << endl; + session = (new TableSessionBuilder()) + ->host("127.0.0.1") + ->rpcPort(6667) + ->username("root") + ->password("root") + ->database("db1") + ->build(); + + cout << "[Show tables from current database(db1)]\n" << endl; try { - SessionDataSet dataSet = session->executeQueryStatement("SHOW TABLES"); - Output(dataSet.getColumnNames()); - while(dataSet.hasNext()) { - Output(dataSet.next()); - } + unique_ptr<SessionDataSet> dataSet = session->executeQueryStatement("SHOW TABLES"); + Output(dataSet); } catch (IoTDBException &e) { cout << e.what() << endl; } - cout << "Change database to db2" << endl; + cout << "[Change database to db2]\n" << endl; try { session->executeNonQueryStatement("USE db2"); } catch (IoTDBException &e) { cout << e.what() << endl; } - cout << "Show tables from current database(db2)" << endl; + cout << "[Show tables from current database(db2)]\n" << endl; try { - SessionDataSet dataSet = session->executeQueryStatement("SHOW TABLES"); - Output(dataSet.getColumnNames()); - while(dataSet.hasNext()) { - Output(dataSet.next()); - } + unique_ptr<SessionDataSet> dataSet = session->executeQueryStatement("SHOW TABLES"); + Output(dataSet); } catch (IoTDBException &e) { cout << e.what() << endl; } - cout << "Drop Database db1,db2" << endl; + cout << "[Drop Database db1,db2]\n" << endl; try { session->executeNonQueryStatement("DROP DATABASE db1"); session->executeNonQueryStatement("DROP DATABASE db2"); diff --git a/iotdb-client/client-cpp/src/main/Session.h b/iotdb-client/client-cpp/src/main/Session.h index 80f93a41d243..32da78397094 100644 --- a/iotdb-client/client-cpp/src/main/Session.h +++ b/iotdb-client/client-cpp/src/main/Session.h @@ -547,13 +547,13 @@ class Field { }; enum class ColumnCategory { - ID, - MEASUREMENT, + TAG, + FIELD, ATTRIBUTE }; template<typename T, typename Target> -const Target* safe_cast(const T& value) { +void safe_cast(const T& value, Target &target) { /* Target Allowed Source Types BOOLEAN BOOLEAN @@ -564,24 +564,27 @@ const Target* safe_cast(const T& value) { TEXT TEXT */ if (std::is_same<Target, T>::value) { - return (Target*)&value; + target = *(Target*)&value; + } else if (std::is_same<Target, string>::value && std::is_array<T>::value && std::is_same<char, typename std::remove_extent<T>::type>::value) { + string tmp((const char*)&value); + target = *(Target*)&tmp; } else if (std::is_same<Target, int64_t>::value && std::is_same<T, int32_t>::value) { int64_t tmp = *(int32_t*)&value; - return (Target*)&tmp; + target = *(Target*)&tmp; } else if (std::is_same<Target, float>::value && std::is_same<T, int32_t>::value) { float tmp = *(int32_t*)&value; - return (Target*)&tmp; + target = *(Target*)&tmp; } else if (std::is_same<Target, double>::value && std::is_same<T, int32_t>::value) { double tmp = *(int32_t*)&value; - return (Target*)&tmp; + target = *(Target*)&tmp; } else if (std::is_same<Target, double>::value && std::is_same<T, int64_t>::value) { double tmp = *(int64_t*)&value; - return (Target*)&tmp; + target = *(Target*)&tmp; } else if (std::is_same<Target, double>::value && std::is_same<T, float>::value) { double tmp = *(float*)&value; - return (Target*)&tmp; + target = *(Target*)&tmp; } else { - throw UnSupportedDataTypeException("Parameter type " + + throw UnSupportedDataTypeException("Error: Parameter type " + std::string(typeid(T).name()) + " cannot be converted to DataType" + std::string(typeid(Target).name())); } @@ -652,7 +655,7 @@ class Tablet { Tablet(const std::string &deviceId, const std::vector<std::pair<std::string, TSDataType::TSDataType>> &schemas, int maxRowNumber) - : Tablet(deviceId, schemas, std::vector<ColumnCategory>(schemas.size(), ColumnCategory::MEASUREMENT), maxRowNumber) {} + : Tablet(deviceId, schemas, std::vector<ColumnCategory>(schemas.size(), ColumnCategory::FIELD), maxRowNumber) {} Tablet(const std::string &deviceId, const std::vector<std::pair<std::string, TSDataType::TSDataType>> &schemas, const std::vector<ColumnCategory> columnTypes, size_t maxRowNumber, bool _isAligned = false) : deviceId(deviceId), schemas(schemas), columnTypes(columnTypes), @@ -699,27 +702,27 @@ class Tablet { TSDataType::TSDataType dataType = schemas[schemaId].second; switch (dataType) { case TSDataType::BOOLEAN: { - ((bool*)values[schemaId])[rowIndex] = *safe_cast<T, bool>(value); + safe_cast<T, bool>(value, ((bool*)values[schemaId])[rowIndex]); break; } case TSDataType::INT32: { - ((int*)values[schemaId])[rowIndex] = *safe_cast<T, int>(value); + safe_cast<T, int>(value, ((int*)values[schemaId])[rowIndex]); break; } case TSDataType::INT64: { - ((int64_t*)values[schemaId])[rowIndex] = *safe_cast<T, int64_t>(value); + safe_cast<T, int64_t>(value, ((int64_t*)values[schemaId])[rowIndex]); break; } case TSDataType::FLOAT: { - ((float*)values[schemaId])[rowIndex] = *safe_cast<T, float>(value); + safe_cast<T, float>(value, ((float*)values[schemaId])[rowIndex]); break; } case TSDataType::DOUBLE: { - ((double*)values[schemaId])[rowIndex] = *safe_cast<T, double>(value); + safe_cast<T, double>(value, ((double*)values[schemaId])[rowIndex]); break; } case TSDataType::TEXT: { - ((string*)values[schemaId])[rowIndex] = *safe_cast<T, string>(value); + safe_cast<T, string>(value, ((string*)values[schemaId])[rowIndex]); break; } default: diff --git a/iotdb-client/client-cpp/src/main/TableSession.cpp b/iotdb-client/client-cpp/src/main/TableSession.cpp index e1c6badc5f6d..304a2f062adc 100644 --- a/iotdb-client/client-cpp/src/main/TableSession.cpp +++ b/iotdb-client/client-cpp/src/main/TableSession.cpp @@ -21,7 +21,7 @@ #include "TableSession.h" -void TableSession::insert(Tablet &tablet, bool sorted = false) { +void TableSession::insert(Tablet &tablet, bool sorted) { session->insertRelationalTablet(tablet, sorted); } void TableSession::executeNonQueryStatement(const string &sql) { diff --git a/iotdb-client/client-cpp/src/main/TableSession.h b/iotdb-client/client-cpp/src/main/TableSession.h index d6e9e23bc9fe..ddaa3d3d6615 100644 --- a/iotdb-client/client-cpp/src/main/TableSession.h +++ b/iotdb-client/client-cpp/src/main/TableSession.h @@ -31,7 +31,7 @@ class TableSession { TableSession(Session* session) { this->session = session; } - void insert(Tablet& tablet, bool sorted); + void insert(Tablet& tablet, bool sorted = false); void executeNonQueryStatement(const std::string& sql); unique_ptr<SessionDataSet> executeQueryStatement(const std::string& sql); unique_ptr<SessionDataSet> executeQueryStatement(const std::string& sql, int64_t timeoutInMs); diff --git a/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp b/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp index 108f025ffc83..dfe77caa273e 100644 --- a/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp +++ b/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp @@ -78,7 +78,7 @@ TEST_CASE("Test insertRelationalTablet", "[testInsertRelationalTablet]") { schemaList.push_back(make_pair("tag1", TSDataType::TEXT)); schemaList.push_back(make_pair("attr1", TSDataType::TEXT)); schemaList.push_back(make_pair("m1", TSDataType::DOUBLE)); - vector<ColumnCategory> columnTypes = {ColumnCategory::ID, ColumnCategory::ATTRIBUTE, ColumnCategory::MEASUREMENT}; + vector<ColumnCategory> columnTypes = {ColumnCategory::TAG, ColumnCategory::ATTRIBUTE, ColumnCategory::FIELD}; int64_t timestamp = 0; Tablet tablet("table1", schemaList, columnTypes, 15);