diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 29c27eaf536434d2f870fc111ca00f5febec1327..083090b871f199ea2ef24728a7f46fd9b862527c 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -35,6 +35,8 @@ set(libcaosdb_INCL ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/logging.h ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/message_code.h ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/protobuf_helper.h + ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/result_table.h + #${CMAKE_CURRENT_SOURCE_DIR}/caosdb/result_set.h ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/status_code.h ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/transaction.h ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/transaction_handler.h diff --git a/include/caosdb/result_table.h b/include/caosdb/result_table.h new file mode 100644 index 0000000000000000000000000000000000000000..393924ca94f3f10499c9028fa13f699d583315f0 --- /dev/null +++ b/include/caosdb/result_table.h @@ -0,0 +1,124 @@ +/* + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2022 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2022 IndiScale GmbH <info@indiscale.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ +#ifndef CAOSDB_RESULT_TABLE_H +#define CAOSDB_RESULT_TABLE_H + +#include "caosdb/value.h" // for Value +#include <iterator> // for iterator, next +#include <memory> // for unique_ptr +#include <string> // for string + +namespace caosdb::transaction { +using caosdb::entity::Value; + +class ResultTableImpl; + +class ResultTableColumnImpl; + +class ResultTableRowImpl; + +class ResultTableRow { +public: + [[nodiscard]] auto GetValue(const std::string &column) const noexcept -> Value; + friend class ResultTable; + explicit ResultTableRow(std::unique_ptr<ResultTableRowImpl> delegate); + +private: + std::unique_ptr<ResultTableRowImpl> delegate; +}; + +class ResultTableColumn { +public: + /** + * Get the name of the column. + */ + [[nodiscard]] auto GetName() const noexcept -> const std::string &; + + friend class ResultTable; + explicit ResultTableColumn(std::unique_ptr<ResultTableColumnImpl> delegate); + +private: + std::unique_ptr<ResultTableColumnImpl> delegate; +}; + +class ResultTable { + class HeaderIterator; + class RowIterator; + +public: + /** + * Number of rows. + * + * The header is not counted as a row. + */ + [[nodiscard]] auto size() const noexcept -> int; + /** + * Get the header of this table, i.e. the list of columns. + */ + [[nodiscard]] auto GetHeader() const noexcept -> HeaderIterator; + /** + * Get the data rows, i.e. the actual data. + */ + [[nodiscard]] auto GetRows() const noexcept -> RowIterator; + + friend class ResultTableImpl; + +private: + class HeaderIterator : std::iterator<std::output_iterator_tag, ResultTableColumn> { + public: + explicit HeaderIterator(const ResultTable *result_table, int index = 0); + HeaderIterator(const HeaderIterator &other); + auto operator*() const -> const ResultTableColumn &; + auto operator++() -> HeaderIterator &; + auto operator++(int) -> HeaderIterator; + auto operator!=(const HeaderIterator &rhs) const -> bool; + auto size() const noexcept -> int; + auto begin() const -> HeaderIterator; + auto end() const -> HeaderIterator; + + private: + int current_index = 0; + const ResultTable *result_table; + }; + + class RowIterator : std::iterator<std::output_iterator_tag, ResultTableRow> { + public: + explicit RowIterator(const ResultTable *result_table, int index = 0); + RowIterator(const RowIterator &other); + auto operator*() const -> const ResultTableRow &; + auto operator++() -> RowIterator &; + auto operator++(int) -> RowIterator; + auto operator!=(const RowIterator &rhs) const -> bool; + auto size() const noexcept -> int; + auto begin() const -> RowIterator; + auto end() const -> RowIterator; + + private: + int current_index = 0; + const ResultTable *result_table; + }; + + explicit ResultTable(std::unique_ptr<ResultTableImpl> delegate); + std::unique_ptr<ResultTableImpl> delegate; +}; + +} // namespace caosdb::transaction +#endif diff --git a/include/caosdb/transaction.h b/include/caosdb/transaction.h index cc889413a3d377c8798dac6cdb471610bb2a6b44..19c3a97dacc2385eef17965935bce88d9c1088c2 100644 --- a/include/caosdb/transaction.h +++ b/include/caosdb/transaction.h @@ -30,7 +30,9 @@ #include "caosdb/logging.h" // for CAOSDB_LOG_ERR... #include "caosdb/protobuf_helper.h" // for get_arena #include "caosdb/status_code.h" // for StatusCode +#include "caosdb/result_table.h" // for ResultTable #include "caosdb/transaction_status.h" // for StatusCode +#include "caosdb/value.h" // for Value #include <algorithm> // for max #include <future> // for async, future #include <google/protobuf/arena.h> // for Arena @@ -166,6 +168,7 @@ namespace caosdb::transaction { using caosdb::entity::Entity; using caosdb::entity::FileDescriptor; +using caosdb::entity::Value; using caosdb::entity::v1::EntityResponse; using caosdb::entity::v1::EntityTransactionService; using caosdb::entity::v1::FileDownloadRequest; @@ -185,62 +188,6 @@ using TransactionResponseCase = caosdb::entity::v1::TransactionResponse::Transac using caosdb::utility::get_arena; using google::protobuf::Arena; -class ResultTableImpl; - -class ResultTableColumnImpl; - -class ResultTableColumn { -public: - /** - * Get the name of the column. - */ - [[nodiscard]] auto GetName() const noexcept -> const std::string &; - - friend class ResultTable; - explicit ResultTableColumn(std::unique_ptr<ResultTableColumnImpl> delegate); -private: - std::unique_ptr<ResultTableColumnImpl> delegate; -}; - -class ResultTable { - class HeaderIterator; - -public: - /** - * Number of rows. - * - * The header is not counted as a row. - */ - [[nodiscard]] auto size() const noexcept -> int; - /** - * Get the header of this table, i.e. the list of columns. - */ - [[nodiscard]] auto GetHeader() const noexcept -> const HeaderIterator; - - friend class ResultTableImpl; - -private: - class HeaderIterator : std::iterator<std::output_iterator_tag, ResultTableColumn> { - public: - explicit HeaderIterator(const ResultTable *result_table, int index = 0); - HeaderIterator(const HeaderIterator &other); - auto operator*() const -> const ResultTableColumn &; - auto operator++() -> HeaderIterator &; - auto operator++(int) -> HeaderIterator; - auto operator!=(const HeaderIterator &rhs) const -> bool; - auto size() const noexcept -> int; - auto begin() const -> HeaderIterator; - auto end() const -> HeaderIterator; - - private: - int current_index = 0; - const ResultTable *result_table; - }; - - explicit ResultTable(std::unique_ptr<ResultTableImpl> delegate); - std::unique_ptr<ResultTableImpl> delegate; -}; - class Transaction; /** diff --git a/include/caosdb/value.h b/include/caosdb/value.h index a92847a82d3cd15ad2dda61e64c6843b99ac6d75..c89bd226bbc618b46d985eb087c540d1c1f35e56 100644 --- a/include/caosdb/value.h +++ b/include/caosdb/value.h @@ -297,6 +297,9 @@ public: this->wrapped->CopyFrom(*value.GetProtoValue()); } explicit inline Value(ProtoValue *wrapped) : ScalarProtoMessageWrapper<ProtoValue>(wrapped) {} + explicit inline Value(const ProtoValue &value) : ScalarProtoMessageWrapper<ProtoValue>() { + this->wrapped->CopyFrom(value); + } explicit inline Value(const std::string &value) : ScalarProtoMessageWrapper<ProtoValue>() { this->wrapped->mutable_scalar_value()->set_string_value(value); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f64bc7671cbe142390ca5439916dfbddd3660294..b4f28930ce2402c2c3a7ea03c994b8a07e492a58 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,6 +27,8 @@ set(libcaosdb_SRC ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/connection.cpp ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/configuration.cpp ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/protobuf_helper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/result_table.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/result_table_impl.h ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/transaction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/transaction_handler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/utility.cpp @@ -45,6 +47,5 @@ IF(BUILD_ACM) ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/acm/user_impl.h ) ENDIF() - # pass variable to parent scope set(libcaosdb_SRC ${libcaosdb_SRC} PARENT_SCOPE) diff --git a/src/caosdb/result_table.cpp b/src/caosdb/result_table.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6fa223bbde47d64944d3fd1aa464beb01dc3e56 --- /dev/null +++ b/src/caosdb/result_table.cpp @@ -0,0 +1,184 @@ + +/* + * This file is a part of the CaosDB Project. + * Copyright (C) 2021-2022 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2021-2022 IndiScale GmbH <info@indiscale.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ +#include "caosdb/result_table.h" // for ResultTable, ResultTab... +#include "caosdb/entity/v1/main.pb.h" // for SelectQueryResult, Sel... +#include "caosdb/protobuf_helper.h" // for ScalarProtoMessageWrapper +#include "caosdb/result_table_impl.h" // for ResultTableImpl, Resul... +#include "caosdb/value.h" // for Value +#include <algorithm> // for max +#include <google/protobuf/repeated_field.h> // IWYU pragma: keep for RepeatedPtrField +#include <memory> // for unique_ptr +#include <string> // for string, operator== +#include <utility> // for move +#include <vector> // for vector +// IWYU pragma: no_include "net/proto2/public/repeated_field.h" + +namespace caosdb::transaction { +using caosdb::entity::Value; +using ProtoSelectQueryResult = caosdb::entity::v1::SelectQueryResult; +using ProtoSelectQueryHeader = caosdb::entity::v1::SelectQueryHeader; +using ProtoSelectQueryColumn = caosdb::entity::v1::SelectQueryColumn; +using ProtoSelectQueryRow = caosdb::entity::v1::SelectQueryRow; +using caosdb::utility::ScalarProtoMessageWrapper; + +ResultTableRowImpl::ResultTableRowImpl(ProtoSelectQueryResult *table, int row) + : header(*table->mutable_header()), row(*table->mutable_data_rows(row)) {} + +auto ResultTableRowImpl::GetColumnIndex(const std::string &column_name) const noexcept -> int { + for (int i = 0; i < this->header.columns_size(); i++) { + if (this->header.columns(i).name() == column_name) { + return i; + } + } + return -1; +} + +auto ResultTableRowImpl::GetValue(const std::string &column) const noexcept -> Value { + const auto column_index = GetColumnIndex(column); + if (column_index == -1) { + // NULL_VALUE + return {}; + } + Value result(this->row.cells(column_index)); + return result; +} + +ResultTableRow::ResultTableRow(std::unique_ptr<ResultTableRowImpl> delegate) + : delegate(std::move(delegate)) {} + +auto ResultTableRow::GetValue(const std::string &column) const noexcept -> Value { + return this->delegate->GetValue(column); +} + +ResultTableColumnImpl::ResultTableColumnImpl(ProtoSelectQueryColumn *column) + : ScalarProtoMessageWrapper<ProtoSelectQueryColumn>(column) {} + +ResultTableColumn::ResultTableColumn(std::unique_ptr<ResultTableColumnImpl> delegate) + : delegate(std::move(delegate)) {} + +auto ResultTableColumn::GetName() const noexcept -> const std::string & { + return this->delegate->wrapped->name(); +} + +auto ResultTableImpl::create(ProtoSelectQueryResult *select_result) + -> std::unique_ptr<ResultTable> { + return std::unique_ptr<ResultTable>( + new ResultTable(std::unique_ptr<ResultTableImpl>(new ResultTableImpl(select_result)))); +} + +ResultTableImpl::ResultTableImpl(ProtoSelectQueryResult *result_table) + : ScalarProtoMessageWrapper<ProtoSelectQueryResult>(result_table) { + for (auto &column : *this->wrapped->mutable_header()->mutable_columns()) { + this->columns.emplace_back( + std::unique_ptr<ResultTableColumnImpl>(new ResultTableColumnImpl(&column))); + } + for (int i = 0; i < this->wrapped->data_rows_size(); i++) { + this->rows.emplace_back( + std::unique_ptr<ResultTableRowImpl>(new ResultTableRowImpl(this->wrapped, i))); + } +} + +ResultTable::ResultTable(std::unique_ptr<ResultTableImpl> delegate) + : delegate(std::move(delegate)) {} + +auto ResultTable::size() const noexcept -> int { return this->delegate->wrapped->data_rows_size(); } + +auto ResultTable::GetRows() const noexcept -> RowIterator { return RowIterator(this, 0); } + +ResultTable::RowIterator::RowIterator(const ResultTable *result_table_param, int index) + : current_index(index), result_table(result_table_param) {} + +ResultTable::RowIterator::RowIterator(const RowIterator &other) + : current_index(other.current_index), result_table(other.result_table) {} + +auto ResultTable::RowIterator::size() const noexcept -> int { + return this->result_table->delegate->wrapped->data_rows_size(); +} + +auto ResultTable::RowIterator::operator*() const -> const ResultTableRow & { + return this->result_table->delegate->rows.at(this->current_index); +} + +auto ResultTable::RowIterator::operator++() -> RowIterator & { + current_index++; + return *this; +} + +auto ResultTable::RowIterator::operator++(int) -> RowIterator { + RowIterator tmp(*this); + operator++(); + return tmp; +} + +auto ResultTable::RowIterator::operator!=(const RowIterator &rhs) const -> bool { + return this->current_index != rhs.current_index; +} + +auto ResultTable::RowIterator::begin() const -> RowIterator { + return RowIterator(this->result_table); +} + +auto ResultTable::RowIterator::end() const -> RowIterator { + return RowIterator(this->result_table, size()); +} + +auto ResultTable::GetHeader() const noexcept -> HeaderIterator { + return HeaderIterator(this, 0); +} + +ResultTable::HeaderIterator::HeaderIterator(const ResultTable *result_table_param, int index) + : current_index(index), result_table(result_table_param) {} + +ResultTable::HeaderIterator::HeaderIterator(const HeaderIterator &other) + : current_index(other.current_index), result_table(other.result_table) {} + +auto ResultTable::HeaderIterator::size() const noexcept -> int { + return this->result_table->delegate->wrapped->header().columns_size(); +} + +auto ResultTable::HeaderIterator::operator*() const -> const ResultTableColumn & { + return this->result_table->delegate->columns.at(this->current_index); +} + +auto ResultTable::HeaderIterator::operator++() -> HeaderIterator & { + current_index++; + return *this; +} + +auto ResultTable::HeaderIterator::operator++(int) -> HeaderIterator { + HeaderIterator tmp(*this); + operator++(); + return tmp; +} + +auto ResultTable::HeaderIterator::operator!=(const HeaderIterator &rhs) const -> bool { + return this->current_index != rhs.current_index; +} + +auto ResultTable::HeaderIterator::begin() const -> HeaderIterator { + return HeaderIterator(this->result_table); +} + +auto ResultTable::HeaderIterator::end() const -> HeaderIterator { + return HeaderIterator(this->result_table, size()); +} + +} // namespace caosdb::transaction diff --git a/src/caosdb/result_table_impl.h b/src/caosdb/result_table_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..3450a68cf7ae0638d42d3ea1c79fd9d181a3eaab --- /dev/null +++ b/src/caosdb/result_table_impl.h @@ -0,0 +1,84 @@ +/* + * This file is a part of the CaosDB Project. + * Copyright (C) 2021-2022 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2021-2022 IndiScale GmbH <info@indiscale.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ +#ifndef CAOSDB_RESULT_TABLE_IMPL_H +#define CAOSDB_RESULT_TABLE_IMPL_H + +#include "caosdb/transaction.h" +#include "caosdb/entity/v1/main.grpc.pb.h" // for EntityTransac... +#include "caosdb/entity/v1/main.pb.h" // for TransactionRe... +#include "caosdb/file_transmission/download_request_handler.h" // Download... +#include "caosdb/file_transmission/file_reader.h" // for path +#include "caosdb/file_transmission/register_file_upload_handler.h" // for RegisterFileUploadHandler +#include "caosdb/file_transmission/upload_request_handler.h" // Upload... +#include "caosdb/logging.h" // for CAOSDB_LOG_FATAL +#include "caosdb/protobuf_helper.h" // for ProtoMessageWrapper +#include "caosdb/status_code.h" // for StatusCode +#include "caosdb/transaction_handler.h" // for EntityTransactionHandler +#include <algorithm> // for max +#include <filesystem> // for operator<<, path +#include <future> // for async, future +#include <google/protobuf/arena.h> // for Arena +#include <grpc/grpc.h> // for gpr_timespec +#include <map> // for map, operator!= +#include <memory> // for unique_ptr +#include <random> // for mt19937, rand... +#include <system_error> // for std::system_error +#include <utility> // for move, pair + +namespace caosdb::transaction { +using caosdb::entity::Value; +using ProtoSelectQueryResult = caosdb::entity::v1::SelectQueryResult; +using ProtoSelectQueryHeader = caosdb::entity::v1::SelectQueryHeader; +using ProtoSelectQueryColumn = caosdb::entity::v1::SelectQueryColumn; +using ProtoSelectQueryRow = caosdb::entity::v1::SelectQueryRow; +using caosdb::utility::ScalarProtoMessageWrapper; + +class ResultTableRowImpl { + explicit ResultTableRowImpl(ProtoSelectQueryResult *table, int row); + [[nodiscard]] auto GetValue(const std::string &column) const noexcept -> Value; + [[nodiscard]] auto GetColumnIndex(const std::string &column) const noexcept -> int; + friend class ResultTableRow; + friend class ResultTableImpl; + ProtoSelectQueryHeader &header; + ProtoSelectQueryRow &row; +}; + +class ResultTableColumnImpl : public ScalarProtoMessageWrapper<ProtoSelectQueryColumn> { + explicit ResultTableColumnImpl(ProtoSelectQueryColumn *column); + friend class ResultTableColumn; + friend class ResultTableImpl; +}; + +class ResultTableImpl : public ScalarProtoMessageWrapper<ProtoSelectQueryResult> { + static auto create(ProtoSelectQueryResult *select_result) -> std::unique_ptr<ResultTable>; + ResultTableImpl(); + explicit ResultTableImpl(ProtoSelectQueryResult *result_table); + std::vector<ResultTableColumn> columns; + std::vector<ResultTableRow> rows; + + friend class ResultTable; + friend class ResultTable::HeaderIterator; + friend class ResultTableColumn; + friend auto ProcessSelectResponse(ProtoSelectQueryResult *select_result) + -> std::unique_ptr<ResultTable>; +}; + +} // namespace caosdb::transaction +#endif diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp index ca8ea2f984f443d0f13dfa50840d85fb03c567bd..5ea5496fc46e807f2be63057ae2aa0efed9f00ae 100644 --- a/src/caosdb/transaction.cpp +++ b/src/caosdb/transaction.cpp @@ -25,7 +25,9 @@ #include "caosdb/file_transmission/register_file_upload_handler.h" // for RegisterFileUploadHandler #include "caosdb/file_transmission/upload_request_handler.h" // Upload... #include "caosdb/logging.h" // for CAOSDB_LOG_FATAL -#include "caosdb/protobuf_helper.h" // for ProtoMessageWrapper +#include "caosdb/protobuf_helper.h" // for ProtoMessageWrapper +#include "caosdb/result_table.h" // for ResultTable +#include "caosdb/result_table_impl.h" // for ResultTableImpl #include "caosdb/status_code.h" // for StatusCode #include "caosdb/transaction_handler.h" // for EntityTransactionHandler #include <algorithm> // for max @@ -53,96 +55,12 @@ using RetrieveResponseCase = caosdb::entity::v1::RetrieveResponse::RetrieveRespo using RetrieveResponse = caosdb::entity::v1::RetrieveResponse; using ProtoEntity = caosdb::entity::v1::Entity; using ProtoSelectQueryResult = caosdb::entity::v1::SelectQueryResult; -using ProtoSelectQueryColumn = caosdb::entity::v1::SelectQueryColumn; using caosdb::entity::v1::EntityRequest; -using caosdb::utility::ScalarProtoMessageWrapper; using google::protobuf::Arena; using NextStatus = grpc::CompletionQueue::NextStatus; using RegistrationStatus = caosdb::entity::v1::RegistrationStatus; -class ResultTableColumnImpl : public ScalarProtoMessageWrapper<ProtoSelectQueryColumn> { - explicit ResultTableColumnImpl(ProtoSelectQueryColumn *column); - friend class ResultTableColumn; - friend class ResultTableImpl; -}; - -ResultTableColumnImpl::ResultTableColumnImpl(ProtoSelectQueryColumn *column) : ScalarProtoMessageWrapper<ProtoSelectQueryColumn>(column) {}; - -ResultTableColumn::ResultTableColumn(std::unique_ptr<ResultTableColumnImpl> delegate) : delegate(std::move(delegate)) {} - -auto ResultTableColumn::GetName() const noexcept -> const std::string & { - return this->delegate->wrapped->name(); -} - -class ResultTableImpl : public ScalarProtoMessageWrapper<ProtoSelectQueryResult> { - static auto create(ProtoSelectQueryResult *select_result) -> std::unique_ptr<ResultTable>; - ResultTableImpl(); - explicit ResultTableImpl(ProtoSelectQueryResult *result_table); - std::vector<ResultTableColumn> columns; - - friend class ResultTable; - friend class ResultTable::HeaderIterator; - friend class ResultTableColumn; - friend auto ProcessSelectResponse(ProtoSelectQueryResult *select_result) -> std::unique_ptr<ResultTable>; -}; - -auto ResultTableImpl::create(ProtoSelectQueryResult *select_result) -> std::unique_ptr<ResultTable> { - return std::unique_ptr<ResultTable>(new ResultTable(std::unique_ptr<ResultTableImpl>(new ResultTableImpl(select_result)))); -} - -ResultTableImpl::ResultTableImpl(ProtoSelectQueryResult *result_table) : ScalarProtoMessageWrapper<ProtoSelectQueryResult>(result_table) { - for (auto &column : *this->wrapped->mutable_header()->mutable_columns()) { - this->columns.emplace_back(std::unique_ptr<ResultTableColumnImpl>(new ResultTableColumnImpl(&column))); - } -} - -ResultTable::ResultTable(std::unique_ptr<ResultTableImpl> delegate) : delegate(std::move(delegate)) {} - -auto ResultTable::size() const noexcept -> int { - // TODO - return 0; -} - -auto ResultTable::GetHeader() const noexcept -> const HeaderIterator { - return HeaderIterator(this, 0); -} - -ResultTable::HeaderIterator::HeaderIterator(const ResultTable *result_table_param, int index) : current_index(index), result_table(result_table_param) {} - -ResultTable::HeaderIterator::HeaderIterator(const HeaderIterator &other) : current_index(other.current_index), result_table(other.result_table) {} - -auto ResultTable::HeaderIterator::size() const noexcept -> int { - return this->result_table->delegate->wrapped->header().columns_size(); -} - -auto ResultTable::HeaderIterator::operator*() const -> const ResultTableColumn & { - return this->result_table->delegate->columns.at(this->current_index); -} - -auto ResultTable::HeaderIterator::operator++() -> HeaderIterator & { - current_index++; - return *this; -} - -auto ResultTable::HeaderIterator::operator++(int) -> HeaderIterator { - HeaderIterator tmp(*this); - operator++(); - return tmp; -} - -auto ResultTable::HeaderIterator::operator!=(const HeaderIterator &rhs) const -> bool { - return this->current_index != rhs.current_index; -} - -auto ResultTable::HeaderIterator::begin() const -> HeaderIterator { - return HeaderIterator(this->result_table); -} - -auto ResultTable::HeaderIterator::end() const -> HeaderIterator { - return HeaderIterator(this->result_table, size()); -} - ResultSet::iterator::iterator(const ResultSet *result_set_param, int index) : current_index(index), result_set(result_set_param) {}