Skip to content
Snippets Groups Projects
Verified Commit 6a8f6ada authored by Timm Fitschen's avatar Timm Fitschen
Browse files

WIP: SELECT for GRPC API

parent daa2ff6e
No related branches found
No related tags found
2 merge requests!45Release 0.2.2,!44F grpc select
Pipeline #29518 failed
Pipeline: caosdb-cppinttest

#29522

    ......@@ -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
    ......
    /*
    * 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
    ......@@ -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;
    /**
    ......
    ......@@ -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);
    }
    ......
    ......@@ -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)
    /*
    * 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
    /*
    * 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
    ......@@ -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) {}
    ......
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Please register or to comment