This is an automated email from the ASF dual-hosted git repository.
isapego pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 70c6382d92 IGNITE-18256 Add RecordView for C++ client (#1891)
70c6382d92 is described below
commit 70c6382d92b870beb4111bb751aa123556651d4e
Author: Igor Sapego <[email protected]>
AuthorDate: Tue Apr 4 13:48:00 2023 +0400
IGNITE-18256 Add RecordView for C++ client (#1891)
---
modules/platforms/cpp/ignite/client/CMakeLists.txt | 2 +
.../cpp/ignite/client/detail/table/table_impl.h | 2 +-
.../cpp/ignite/client/table/record_view.h | 582 ++++++++++-
.../platforms/cpp/ignite/client/table/table.cpp | 6 +-
modules/platforms/cpp/ignite/client/table/table.h | 19 +-
modules/platforms/cpp/ignite/client/type_mapping.h | 86 ++
.../platforms/cpp/tests/client-test/CMakeLists.txt | 1 +
.../client-test/key_value_binary_view_test.cpp | 4 +-
.../tests/client-test/record_binary_view_test.cpp | 6 +-
.../cpp/tests/client-test/record_view_test.cpp | 1083 ++++++++++++++++++++
.../cpp/tests/client-test/tables_test.cpp | 12 +-
.../cpp/tests/client-test/transactions_test.cpp | 36 +-
12 files changed, 1782 insertions(+), 57 deletions(-)
diff --git a/modules/platforms/cpp/ignite/client/CMakeLists.txt
b/modules/platforms/cpp/ignite/client/CMakeLists.txt
index e77c9f1f0f..f29ba9740a 100644
--- a/modules/platforms/cpp/ignite/client/CMakeLists.txt
+++ b/modules/platforms/cpp/ignite/client/CMakeLists.txt
@@ -44,6 +44,8 @@ set(PUBLIC_HEADERS
ignite_client.h
ignite_client_configuration.h
ignite_logger.h
+ primitive.h
+ type_mapping.h
compute/compute.h
network/cluster_node.h
sql/sql.h
diff --git a/modules/platforms/cpp/ignite/client/detail/table/table_impl.h
b/modules/platforms/cpp/ignite/client/detail/table/table_impl.h
index 4a6395910a..88d0b8ca94 100644
--- a/modules/platforms/cpp/ignite/client/detail/table/table_impl.h
+++ b/modules/platforms/cpp/ignite/client/detail/table/table_impl.h
@@ -232,7 +232,7 @@ public:
*
* @param tx Optional transaction. If nullptr implicit transaction for this
* single operation is used.
- * @param key A record with key columns set..
+ * @param key A record with key columns set.
* @param callback Callback that is called on operation completion. Called
with
* a value indicating whether a record with the specified key was
deleted.
*/
diff --git a/modules/platforms/cpp/ignite/client/table/record_view.h
b/modules/platforms/cpp/ignite/client/table/record_view.h
index 5a9d10b298..8c7b3c5db5 100644
--- a/modules/platforms/cpp/ignite/client/table/record_view.h
+++ b/modules/platforms/cpp/ignite/client/table/record_view.h
@@ -17,11 +17,12 @@
#pragma once
-#include "ignite/client/table/ignite_tuple.h"
-#include "ignite/client/transaction/transaction.h"
+#include <ignite/client/table/ignite_tuple.h>
+#include <ignite/client/transaction/transaction.h>
+#include <ignite/client/type_mapping.h>
-#include "ignite/common/config.h"
-#include "ignite/common/ignite_result.h"
+#include <ignite/common/config.h>
+#include <ignite/common/ignite_result.h>
#include <memory>
#include <type_traits>
@@ -36,23 +37,8 @@ namespace detail {
class table_impl;
}
-/**
- * Record view interface provides methods to access table records.
- */
template<typename T>
-class record_view {
-public:
- typedef typename std::decay<T>::type value_type;
-
- // Deleted
- record_view(const record_view &) = delete;
- record_view &operator=(const record_view &) = delete;
-
- // Default
- record_view() = default;
- record_view(record_view &&) noexcept = default;
- record_view &operator=(record_view &&) noexcept = default;
-};
+class record_view;
/**
* Record view interface provides methods to access table records.
@@ -337,7 +323,7 @@ public:
*
* @param tx Optional transaction. If nullptr implicit transaction for this
* single operation is used.
- * @param key A record with key columns set..
+ * @param key A record with key columns set.
* @param callback Callback that is called on operation completion. Called
with
* a value indicating whether a record with the specified key was
deleted.
*/
@@ -475,4 +461,558 @@ private:
std::shared_ptr<detail::table_impl> m_impl;
};
+
+/**
+ * Record view interface provides methods to access table records.
+ */
+template<typename T>
+class record_view {
+ friend class table;
+
+public:
+ typedef typename std::decay<T>::type value_type;
+
+ // Deleted
+ record_view(const record_view &) = delete;
+ record_view &operator=(const record_view &) = delete;
+
+ // Default
+ record_view() = default;
+ record_view(record_view &&) noexcept = default;
+ record_view &operator=(record_view &&) noexcept = default;
+
+ /**
+ * Gets a record by key asynchronously.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param key Key.
+ * @param callback Callback which is called on success with value if it
+ * exists and @c std::nullopt otherwise
+ */
+ void get_async(transaction *tx, const value_type &key,
ignite_callback<std::optional<value_type>> callback) {
+ m_delegate.get_async(tx, convert_to_tuple(key), [callback =
std::move(callback)] (auto res) {
+ callback(convert_result(std::move(res)));
+ });
+ }
+
+ /**
+ * Gets a record by key.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param key Key.
+ * @return Value if exists and @c std::nullopt otherwise.
+ */
+ [[nodiscard]] std::optional<value_type> get(transaction *tx, const
value_type &key) {
+ return sync<std::optional<value_type>>(
+ [this, tx, &key](auto callback) { get_async(tx, key,
std::move(callback)); });
+ }
+
+ /**
+ * Gets multiple records by keys asynchronously.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param keys Keys.
+ * @param callback Callback that is called on operation completion. Called
with
+ * resulting records with all columns filled from the table. The order of
+ * elements is guaranteed to be the same as the order of keys. If a
record
+ * does not exist, the resulting element of the corresponding order is
+ * @c std::nullopt.
+ */
+ void get_all_async(transaction *tx, std::vector<value_type> keys,
+ ignite_callback<std::vector<std::optional<value_type>>> callback) {
+ m_delegate.get_all_async(tx, values_to_tuples(std::move(keys)),
[callback = std::move(callback)] (auto res) {
+ callback(convert_result(std::move(res)));
+ });
+ }
+
+ /**
+ * Gets multiple records by keys.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param keys Keys.
+ * @return Resulting records with all columns filled from the table.
+ * The order of elements is guaranteed to be the same as the order of
+ * keys. If a record does not exist, the resulting element of the
+ * corresponding order is @c std::nullopt.
+ */
+ [[nodiscard]] std::vector<std::optional<value_type>> get_all(transaction
*tx, std::vector<value_type> keys) {
+ return sync<std::vector<std::optional<value_type>>>([this, tx, keys =
std::move(keys)](auto callback) mutable {
+ get_all_async(tx, std::move(keys), std::move(callback));
+ });
+ }
+
+ /**
+ * Inserts a record into the table if does not exist or replaces the
existing one.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record to insert into the table. The record cannot be
@c nullptr.
+ * @param callback Callback.
+ */
+ void upsert_async(transaction *tx, const value_type &record,
ignite_callback<void> callback) {
+ m_delegate.upsert_async(tx, convert_to_tuple(record),
std::move(callback));
+ }
+
+ /**
+ * Inserts a record into the table if does not exist or replaces the
existing one.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record to insert into the table. The record cannot be
@c nullptr.
+ */
+ void upsert(transaction *tx, const value_type &record) {
+ sync<void>([this, tx, &record](auto callback) { upsert_async(tx,
record, std::move(callback)); });
+ }
+
+ /**
+ * Inserts multiple records into the table asynchronously, replacing
+ * existing.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param records Records to upsert.
+ * @param callback Callback that is called on operation completion.
+ */
+ void upsert_all_async(transaction *tx, std::vector<value_type> records,
ignite_callback<void> callback) {
+ m_delegate.upsert_all_async(tx, values_to_tuples(std::move(records)),
std::move(callback));
+ }
+
+ /**
+ * Inserts multiple records into the table, replacing existing.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param records Records to upsert.
+ */
+ void upsert_all(transaction *tx, std::vector<value_type> records) {
+ sync<void>([this, tx, records = std::move(records)](auto callback)
mutable {
+ upsert_all_async(tx, std::move(records), std::move(callback));
+ });
+ }
+
+ /**
+ * Inserts a record into the table and returns previous record
asynchronously.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record to upsert.
+ * @param callback Callback. Called with a value which contains replaced
+ * record or @c std::nullopt if it did not exist.
+ */
+ void get_and_upsert_async(
+ transaction *tx, const value_type &record,
ignite_callback<std::optional<value_type>> callback) {
+ m_delegate.get_and_upsert_async(tx, convert_to_tuple(record),
[callback = std::move(callback)] (auto res) {
+ callback(convert_result(std::move(res)));
+ });
+ }
+
+ /**
+ * Inserts a record into the table and returns previous record.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record to upsert.
+ * @return A replaced record or @c std::nullopt if it did not exist.
+ */
+ [[nodiscard]] std::optional<value_type> get_and_upsert(transaction *tx,
const value_type &record) {
+ return sync<std::optional<value_type>>(
+ [this, tx, &record](auto callback) { get_and_upsert_async(tx,
record, std::move(callback)); });
+ }
+
+ /**
+ * Inserts a record into the table if it does not exist asynchronously.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record to insert into the table.
+ * @param callback Callback. Called with a value indicating whether the
+ * record was inserted. Equals @c false if a record with the same key
+ * already exists.
+ */
+ void insert_async(transaction *tx, const value_type &record,
ignite_callback<bool> callback) {
+ m_delegate.insert_async(tx, convert_to_tuple(record),
std::move(callback));
+ }
+
+ /**
+ * Inserts a record into the table if does not exist.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record to insert into the table.
+ */
+ bool insert(transaction *tx, const value_type &record) {
+ return sync<bool>([this, tx, &record](auto callback) {
insert_async(tx, record, std::move(callback)); });
+ }
+
+ /**
+ * Inserts multiple records into the table asynchronously, skipping
existing ones.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param records Records to insert.
+ * @param callback Callback that is called on operation completion. Called
with
+ * skipped records.
+ */
+ void insert_all_async(
+ transaction *tx, std::vector<value_type> records,
ignite_callback<std::vector<value_type>> callback) {
+ m_delegate.insert_all_async(tx, values_to_tuples(std::move(records)),
+ [callback = std::move(callback)] (auto res) {
+ callback(convert_result(std::move(res)));
+ }
+ );
+ }
+
+ /**
+ * Inserts multiple records into the table, skipping existing ones.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param records Records to insert.
+ * @return Skipped records.
+ */
+ std::vector<value_type> insert_all(transaction *tx,
std::vector<value_type> records) {
+ return sync<std::vector<value_type>>([this, tx, records =
std::move(records)](auto callback) mutable {
+ insert_all_async(tx, std::move(records), std::move(callback));
+ });
+ }
+
+ /**
+ * Asynchronously replaces a record with the same key columns if it exists,
+ * otherwise does nothing.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record to insert into the table.
+ * @param callback Callback. Called with a value indicating whether a
record
+ * with the specified key was replaced.
+ */
+ void replace_async(transaction *tx, const value_type &record,
ignite_callback<bool> callback) {
+ m_delegate.replace_async(tx, convert_to_tuple(record),
std::move(callback));
+ }
+
+ /**
+ * Replaces a record with the same key columns if it exists, otherwise does
+ * nothing.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record to insert into the table.
+ * @return A value indicating whether a record with the specified key was
+ * replaced.
+ */
+ bool replace(transaction *tx, const value_type &record) {
+ return sync<bool>([this, tx, &record](auto callback) {
replace_async(tx, record, std::move(callback)); });
+ }
+
+ /**
+ * Asynchronously replaces a record with a new one only if all existing
+ * columns have the same values as the specified @c record.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record Current value of the record to be replaced.
+ * @param new_record A record to replace it with.
+ * @param callback Callback. Called with a value indicating whether a
+ * specified record was replaced.
+ */
+ void replace_async(
+ transaction *tx, const value_type &record, const value_type
&new_record, ignite_callback<bool> callback) {
+ m_delegate.replace_async(tx, convert_to_tuple(record),
convert_to_tuple(new_record), std::move(callback));
+ }
+
+ /**
+ * Replaces a record with a new one only if all existing columns have
+ * the same values as the specified @c record.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record Current value of the record to be replaced.
+ * @param new_record A record to replace it with.
+ * @return A value indicating whether a specified record was replaced.
+ */
+ bool replace(transaction *tx, const value_type &record, const value_type
&new_record) {
+ return sync<bool>([this, tx, &record, &new_record] (auto callback) {
+ replace_async(tx, record, new_record, std::move(callback));
+ });
+ }
+
+ /**
+ * Asynchronously replaces a record with the same key columns if it exists
+ * returning previous record value.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record to insert.
+ * @param callback Callback. Called with a previous value for the given
key,
+ * or @c std::nullopt if it did not exist.
+ */
+ void get_and_replace_async(
+ transaction *tx, const value_type &record,
ignite_callback<std::optional<value_type>> callback) {
+ m_delegate.get_and_replace_async(tx, convert_to_tuple(record),
[callback = std::move(callback)] (auto res) {
+ callback(convert_result(std::move(res)));
+ });
+ }
+
+ /**
+ * Replaces a record with the same key columns if it exists returning
+ * previous record value.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record to insert.
+ * @param callback A previous value for the given key, or @c std::nullopt
if
+ * it did not exist.
+ */
+ [[nodiscard]] std::optional<value_type> get_and_replace(transaction *tx,
const value_type &record) {
+ return sync<std::optional<value_type>>(
+ [this, tx, &record](auto callback) { get_and_replace_async(tx,
record, std::move(callback)); });
+ }
+
+ /**
+ * Deletes a record with the specified key asynchronously.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param key A record with key columns set.
+ * @param callback Callback that is called on operation completion. Called
with
+ * a value indicating whether a record with the specified key was
deleted.
+ */
+ void remove_async(transaction *tx, const value_type &key,
ignite_callback<bool> callback) {
+ m_delegate.remove_async(tx, convert_to_tuple(key),
std::move(callback));
+ }
+
+ /**
+ * Deletes a record with the specified key.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param key A record with key columns set.
+ * @return A value indicating whether a record with the specified key was
deleted.
+ */
+ bool remove(transaction *tx, const value_type &record) {
+ return sync<bool>([this, tx, &record](auto callback) {
remove_async(tx, record, std::move(callback)); });
+ }
+
+ /**
+ * Deletes a record only if all existing columns have the same values as
+ * the specified record asynchronously.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record with all columns set.
+ * @param callback Callback that is called on operation completion. Called
with
+ * a value indicating whether a record with the specified key was
deleted.
+ */
+ void remove_exact_async(transaction *tx, const value_type &record,
ignite_callback<bool> callback) {
+ m_delegate.remove_exact_async(tx, convert_to_tuple(record),
std::move(callback));
+ }
+
+ /**
+ * Deletes a record only if all existing columns have the same values as
+ * the specified record.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param record A record with all columns set.
+ * @return A value indicating whether a record with the specified key was
+ * deleted.
+ */
+ bool remove_exact(transaction *tx, const value_type &record) {
+ return sync<bool>([this, tx, &record](auto callback) {
remove_exact_async(tx, record, std::move(callback)); });
+ }
+
+ /**
+ * Gets and deletes a record with the specified key asynchronously.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param key A record with key columns set.
+ * @param callback Callback that is called on operation completion. Called
with
+ * a deleted record or @c std::nullopt if it did not exist.
+ */
+ void get_and_remove_async(
+ transaction *tx, const value_type &key,
ignite_callback<std::optional<value_type>> callback) {
+ m_delegate.get_and_remove_async(tx, convert_to_tuple(key), [callback =
std::move(callback)] (auto res) {
+ callback(convert_result(std::move(res)));
+ });
+ }
+
+ /**
+ * Gets and deletes a record with the specified key.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param key A record with key columns set.
+ * @return A deleted record or @c std::nullopt if it did not exist.
+ */
+ std::optional<value_type> get_and_remove(transaction *tx, const value_type
&key) {
+ return sync<std::optional<value_type>>(
+ [this, tx, &key](auto callback) { get_and_remove_async(tx, key,
std::move(callback)); });
+ }
+
+ /**
+ * Deletes multiple records from the table asynchronously. If one or more
+ * keys do not exist, other records are still deleted
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param keys Record keys to delete.
+ * @param callback Callback that is called on operation completion. Called
with
+ * records from @c keys that did not exist.
+ */
+ void remove_all_async(
+ transaction *tx, std::vector<value_type> keys,
ignite_callback<std::vector<value_type>> callback) {
+ m_delegate.remove_all_async(tx, values_to_tuples(std::move(keys)),
[callback = std::move(callback)] (auto res) {
+ callback(convert_result(std::move(res)));
+ });
+ }
+
+ /**
+ * Deletes multiple records from the table If one or more keys do not
exist,
+ * other records are still deleted
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param keys Record keys to delete.
+ * @return Records from @c keys that did not exist.
+ */
+ std::vector<value_type> remove_all(transaction *tx,
std::vector<value_type> keys) {
+ return sync<std::vector<value_type>>([this, tx, keys =
std::move(keys)](auto callback) mutable {
+ remove_all_async(tx, std::move(keys), std::move(callback));
+ });
+ }
+
+ /**
+ * Deletes multiple exactly matching records asynchronously. If one or more
+ * records do not exist, other records are still deleted.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param records Records to delete.
+ * @param callback Callback that is called on operation completion. Called
with
+ * records from @c records that did not exist.
+ */
+ void remove_all_exact_async(
+ transaction *tx, std::vector<value_type> records,
ignite_callback<std::vector<value_type>> callback) {
+ m_delegate.remove_all_exact_async(tx,
values_to_tuples(std::move(records)),
+ [callback = std::move(callback)] (auto res) {
+ callback(convert_result(std::move(res)));
+ }
+ );
+ }
+
+ /**
+ * Deletes multiple exactly matching records. If one or more records do not
+ * exist, other records are still deleted.
+ *
+ * @param tx Optional transaction. If nullptr implicit transaction for this
+ * single operation is used.
+ * @param records Records to delete.
+ * @return Records from @c records that did not exist.
+ */
+ std::vector<value_type> remove_all_exact(transaction *tx,
std::vector<value_type> records) {
+ return sync<std::vector<value_type>>([this, tx, records =
std::move(records)](auto callback) mutable {
+ remove_all_exact_async(tx, std::move(records),
std::move(callback));
+ });
+ }
+
+private:
+ /**
+ * Convert values to tuples.
+ * @param vals Values.
+ * @return Tuples.
+ */
+ static std::vector<ignite_tuple> values_to_tuples(std::vector<value_type>
values) {
+ //TODO: Optimize memory usage (IGNITE-19198)
+ std::vector<ignite_tuple> tuples;
+ tuples.reserve(values.size());
+ for (auto &&value : std::move(values)) {
+ tuples.push_back(convert_to_tuple(std::move(value)));
+ }
+ return tuples;
+ }
+
+ /**
+ * Tuples to values.
+ * @param tuples Tuples.
+ * @return Values.
+ */
+ static std::vector<value_type> tuples_to_values(std::vector<ignite_tuple>
tuples) {
+ //TODO: Optimize memory usage (IGNITE-19198)
+ std::vector<value_type> values;
+ values.reserve(tuples.size());
+ for (auto &&tuple : std::move(tuples)) {
+
values.emplace_back(convert_from_tuple<value_type>(std::move(tuple)));
+ }
+ return values;
+ }
+
+ /**
+ * Optional tuples to optional values.
+ * @param tuples Tuples.
+ * @return Values.
+ */
+ static std::vector<std::optional<value_type>>
tuples_to_values(std::vector<std::optional<ignite_tuple>> tuples) {
+ //TODO: Optimize memory usage (IGNITE-19198)
+ std::vector<std::optional<value_type>> values;
+ values.reserve(tuples.size());
+ for (auto &&tuple : std::move(tuples)) {
+
values.emplace_back(convert_from_tuple<value_type>(std::move(tuple)));
+ }
+ return values;
+ }
+
+ /**
+ * Convert result from tuple-based type to user type.
+ * @param res Result to convert.
+ * @return Converted result.
+ */
+ static ignite_result<std::optional<value_type>>
convert_result(ignite_result<std::optional<ignite_tuple>> &&res) {
+ if (res.has_error())
+ return {std::move(res).error()};
+
+ return {convert_from_tuple<value_type>(std::move(res).value())};
+ }
+
+ /**
+ * Convert result from tuple-based type to user type.
+ * @param res Result to convert.
+ * @return Converted result.
+ */
+ static ignite_result<std::vector<std::optional<value_type>>>
convert_result(
+ ignite_result<std::vector<std::optional<ignite_tuple>>> &&res) {
+ if (res.has_error())
+ return {std::move(res).error()};
+
+ return {tuples_to_values(std::move(res).value())};
+ }
+
+ /**
+ * Convert result from tuple-based type to user type.
+ * @param res Result to convert.
+ * @return Converted result.
+ */
+ static ignite_result<std::vector<value_type>>
convert_result(ignite_result<std::vector<ignite_tuple>> &&res) {
+ if (res.has_error())
+ return {std::move(res).error()};
+
+ return {tuples_to_values(std::move(res).value())};
+ }
+
+ /**
+ * Constructor
+ *
+ * @param impl Implementation
+ */
+ explicit record_view(record_view<ignite_tuple> delegate)
+ : m_delegate(std::move(delegate)) {}
+
+ /** Delegate. */
+ record_view<ignite_tuple> m_delegate;
+};
+
} // namespace ignite
diff --git a/modules/platforms/cpp/ignite/client/table/table.cpp
b/modules/platforms/cpp/ignite/client/table/table.cpp
index 438ae117cd..9c2219d90d 100644
--- a/modules/platforms/cpp/ignite/client/table/table.cpp
+++ b/modules/platforms/cpp/ignite/client/table/table.cpp
@@ -20,15 +20,15 @@
namespace ignite {
-const std::string &table::name() const noexcept {
+const std::string &table::get_name() const noexcept {
return m_impl->name();
}
-record_view<ignite_tuple> table::record_binary_view() const noexcept {
+record_view<ignite_tuple> table::get_record_binary_view() const noexcept {
return record_view<ignite_tuple>{m_impl};
}
-key_value_view<ignite_tuple, ignite_tuple> table::key_value_binary_view()
const noexcept {
+key_value_view<ignite_tuple, ignite_tuple> table::get_key_value_binary_view()
const noexcept {
return key_value_view<ignite_tuple, ignite_tuple>{m_impl};
}
diff --git a/modules/platforms/cpp/ignite/client/table/table.h
b/modules/platforms/cpp/ignite/client/table/table.h
index 24721dacde..e1097ebb2c 100644
--- a/modules/platforms/cpp/ignite/client/table/table.h
+++ b/modules/platforms/cpp/ignite/client/table/table.h
@@ -56,21 +56,34 @@ public:
*
* @return Table name.
*/
- [[nodiscard]] IGNITE_API const std::string &name() const noexcept;
+ [[nodiscard]] IGNITE_API const std::string &get_name() const noexcept;
/**
* Gets the record binary view.
*
* @return Record binary view.
*/
- [[nodiscard]] IGNITE_API record_view<ignite_tuple> record_binary_view()
const noexcept;
+ [[nodiscard]] IGNITE_API record_view<ignite_tuple>
get_record_binary_view() const noexcept;
+
+ /**
+ * Gets the record view for the type.
+ *
+ * Template functions @c convert_to_tuple() and @c convert_from_tuple()
should be specialized for the type T.
+ * @see See type_mapping.h for details.
+ *
+ * @return Record view.
+ */
+ template<typename T>
+ [[nodiscard]] record_view<T> get_record_view() const noexcept {
+ return record_view<T>{get_record_binary_view()};
+ }
/**
* Gets the key-value binary view.
*
* @return Record binary view.
*/
- [[nodiscard]] IGNITE_API key_value_view<ignite_tuple, ignite_tuple>
key_value_binary_view() const noexcept;
+ [[nodiscard]] IGNITE_API key_value_view<ignite_tuple, ignite_tuple>
get_key_value_binary_view() const noexcept;
private:
/**
diff --git a/modules/platforms/cpp/ignite/client/type_mapping.h
b/modules/platforms/cpp/ignite/client/type_mapping.h
new file mode 100644
index 0000000000..55eb3a3b64
--- /dev/null
+++ b/modules/platforms/cpp/ignite/client/type_mapping.h
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <ignite/client/table/ignite_tuple.h>
+
+namespace ignite {
+
+/**
+ * Function that specifies how a value of a type should be converted to @c
ignite_tuple.
+ *
+ * @tparam T Type of the value.
+ * @param value Value to convert.
+ * @return An instance of @c ignite_tuple.
+ */
+template<typename T>
+ignite_tuple convert_to_tuple(T &&value);
+
+/**
+ * Function that specifies how an @c ignite_tuple instance should be converted
to specific type.
+ *
+ * @tparam T Type to convert to.
+ * @param value Instance of the @c ignite_tuple type.
+ * @return A resulting value.
+ */
+template<typename T>
+T convert_from_tuple(ignite_tuple &&value);
+
+/**
+ * Specialisation for const-references.
+ *
+ * @tparam T Type to convert from.
+ * @param value Value.
+ * @return Tuple.
+ */
+template<typename T>
+ignite_tuple convert_to_tuple(const T &value) {
+ return convert_to_tuple(T(value));
+}
+
+/**
+ * Specialisation for optionals.
+ *
+ * @tparam T Type to convert from.
+ * @param value Optional value.
+ * @return Optional tuple.
+ */
+template<typename T>
+std::optional<ignite_tuple> convert_to_tuple(std::optional<T> &&value) {
+ if (!value.has_value())
+ return std::nullopt;
+
+ return {convert_to_tuple<T>(*std::move(value))};
+}
+
+/**
+ * Specialisation for optionals.
+ *
+ * @tparam T Type to convert to.
+ * @param value Optional tuple.
+ * @return Optional value.
+ */
+template<typename T>
+std::optional<T> convert_from_tuple(std::optional<ignite_tuple> &&value) {
+ if (!value.has_value())
+ return std::nullopt;
+
+ return {convert_from_tuple<T>(*std::move(value))};
+}
+
+} // namespace ignite
diff --git a/modules/platforms/cpp/tests/client-test/CMakeLists.txt
b/modules/platforms/cpp/tests/client-test/CMakeLists.txt
index 2d9611905f..c8772c72e5 100644
--- a/modules/platforms/cpp/tests/client-test/CMakeLists.txt
+++ b/modules/platforms/cpp/tests/client-test/CMakeLists.txt
@@ -27,6 +27,7 @@ set(SOURCES
key_value_binary_view_test.cpp
main.cpp
record_binary_view_test.cpp
+ record_view_test.cpp
sql_test.cpp
tables_test.cpp
transactions_test.cpp
diff --git
a/modules/platforms/cpp/tests/client-test/key_value_binary_view_test.cpp
b/modules/platforms/cpp/tests/client-test/key_value_binary_view_test.cpp
index c48fca21dd..a0627cc657 100644
--- a/modules/platforms/cpp/tests/client-test/key_value_binary_view_test.cpp
+++ b/modules/platforms/cpp/tests/client-test/key_value_binary_view_test.cpp
@@ -39,7 +39,7 @@ protected:
m_client = ignite_client::start(cfg, std::chrono::seconds(30));
auto table = m_client.get_tables().get_table(TABLE_1);
- kv_view = table->key_value_binary_view();
+ kv_view = table->get_key_value_binary_view();
}
void TearDown() override {
@@ -931,7 +931,7 @@ TEST_F(key_value_binary_view_test, remove_all_exact_empty) {
TEST_F(key_value_binary_view_test, types_test) {
auto table = m_client.get_tables().get_table(TABLE_NAME_ALL_COLUMNS);
- kv_view = table->key_value_binary_view();
+ kv_view = table->get_key_value_binary_view();
ignite_tuple inserted{
{"str", "test"},
diff --git
a/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp
b/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp
index d79f7fb9ea..fd95e93e61 100644
--- a/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp
+++ b/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp
@@ -39,7 +39,7 @@ protected:
m_client = ignite_client::start(cfg, std::chrono::seconds(30));
auto table = m_client.get_tables().get_table(TABLE_1);
- tuple_view = table->record_binary_view();
+ tuple_view = table->get_record_binary_view();
}
void TearDown() override {
@@ -774,7 +774,7 @@ TEST_F(record_binary_view_test, remove_exact_empty_throws) {
}
TEST_F(record_binary_view_test, get_and_remove_nonexisting) {
- auto res = tuple_view.get_and_replace(nullptr, get_tuple(42, "foo"));
+ auto res = tuple_view.get_and_remove(nullptr, get_tuple(42, "foo"));
ASSERT_FALSE(res.has_value());
auto res_tuple = tuple_view.get(nullptr, get_tuple(42));
@@ -938,7 +938,7 @@ TEST_F(record_binary_view_test, remove_all_exact_empty) {
TEST_F(record_binary_view_test, types_test) {
auto table = m_client.get_tables().get_table(TABLE_NAME_ALL_COLUMNS);
- tuple_view = table->record_binary_view();
+ tuple_view = table->get_record_binary_view();
ignite_tuple inserted{
{"key", std::int64_t(42)},
diff --git a/modules/platforms/cpp/tests/client-test/record_view_test.cpp
b/modules/platforms/cpp/tests/client-test/record_view_test.cpp
new file mode 100644
index 0000000000..a8f882eb5c
--- /dev/null
+++ b/modules/platforms/cpp/tests/client-test/record_view_test.cpp
@@ -0,0 +1,1083 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ignite_runner_suite.h"
+#include "tests/test-common/test_utils.h"
+
+#include "ignite/client/ignite_client.h"
+#include "ignite/client/ignite_client_configuration.h"
+
+#include <gmock/gmock-matchers.h>
+#include <gtest/gtest.h>
+
+#include <chrono>
+
+using namespace ignite;
+
+/**
+ * Test table type mapping (@see ignite_runner_suite::TABLE_1).
+ */
+struct test_type {
+ test_type() = default;
+ explicit test_type(std::int64_t key) : key(key) {}
+ explicit test_type(std::string val) : val(std::move(val)) {}
+ explicit test_type(std::int64_t key, std::string val) : key(key),
val(std::move(val)) {}
+
+ std::int64_t key{0};
+ std::string val;
+};
+
+struct wrong_mapping_key {
+ wrong_mapping_key() = default;
+ explicit wrong_mapping_key(std::int64_t key) : key(key) {}
+ explicit wrong_mapping_key(std::string val) : val(std::move(val)) {}
+ explicit wrong_mapping_key(std::int64_t key, std::string val) : key(key),
val(std::move(val)) {}
+
+ std::int64_t key{0};
+ std::string val;
+};
+
+struct wrong_mapping_value {
+ wrong_mapping_value() = default;
+ explicit wrong_mapping_value(std::int64_t key) : key(key) {}
+ explicit wrong_mapping_value(std::string val) : val(std::move(val)) {}
+ explicit wrong_mapping_value(std::int64_t key, std::string val) :
key(key), val(std::move(val)) {}
+
+ std::int64_t key{0};
+ std::string val;
+};
+
+namespace ignite {
+
+template<>
+ignite_tuple convert_to_tuple(test_type &&value) {
+ ignite_tuple tuple;
+
+ tuple.set("key", value.key);
+ tuple.set("val", value.val);
+
+ return tuple;
+}
+
+template<>
+test_type convert_from_tuple(ignite_tuple&& value) {
+ test_type res;
+
+ res.key = value.get<std::int64_t>("key");
+
+ if (value.column_count() > 1)
+ res.val = value.get<std::string>("val");
+
+ return res;
+}
+
+template<>
+ignite_tuple convert_to_tuple(wrong_mapping_key &&value) {
+ ignite_tuple tuple;
+
+ tuple.set("id", value.key);
+ tuple.set("val", value.val);
+
+ return tuple;
+}
+
+template<>
+wrong_mapping_key convert_from_tuple(ignite_tuple&& value) {
+ wrong_mapping_key res;
+
+ res.key = value.get<std::int64_t>("id");
+
+ if (value.column_count() > 1)
+ res.val = value.get<std::string>("val");
+
+ return res;
+}
+
+template<>
+ignite_tuple convert_to_tuple(wrong_mapping_value &&value) {
+ ignite_tuple tuple;
+
+ tuple.set("key", value.key);
+ tuple.set("str", value.val);
+
+ return tuple;
+}
+
+template<>
+wrong_mapping_value convert_from_tuple(ignite_tuple&& value) {
+ wrong_mapping_value res;
+
+ res.key = value.get<std::int64_t>("key");
+
+ if (value.column_count() > 1)
+ res.val = value.get<std::string>("str");
+
+ return res;
+}
+
+}
+
+/**
+ * Test suite.
+ */
+class record_view_test : public ignite_runner_suite {
+protected:
+ void SetUp() override {
+ ignite_client_configuration cfg{get_node_addrs()};
+ cfg.set_logger(get_logger());
+
+ m_client = ignite_client::start(cfg, std::chrono::seconds(30));
+ auto table = m_client.get_tables().get_table(TABLE_1);
+
+ view = table->get_record_view<test_type>();
+ }
+
+ void TearDown() override {
+ std::vector<test_type> work_range;
+ work_range.reserve(200);
+ for (std::int64_t i = -100; i < 100; ++i)
+ work_range.emplace_back(i);
+
+ view.remove_all(nullptr, work_range);
+ }
+
+ /** Ignite client. */
+ ignite_client m_client;
+
+ /** Record binary view. */
+ record_view<test_type> view;
+};
+
+TEST_F(record_view_test, wrong_mapped_key_throws) {
+ {
+ test_type val{1, "foo"};
+ view.upsert(nullptr, val);
+ }
+
+ auto table = m_client.get_tables().get_table(TABLE_1);
+ auto wrong_view = table->get_record_view<wrong_mapping_key>();
+
+ wrong_mapping_key key{1};
+ wrong_mapping_key val{1, "foo"};
+
+ EXPECT_THROW(
+ {
+ try {
+ wrong_view.upsert(nullptr, val);
+ } catch (const ignite_error &e) {
+ EXPECT_THAT(e.what_str(), testing::HasSubstr("Missed key
column: KEY"));
+ throw;
+ }
+ },
+ ignite_error);
+
+ EXPECT_THROW(
+ {
+ try {
+ (void) wrong_view.get(nullptr, key);
+ } catch (const ignite_error &e) {
+ EXPECT_THAT(e.what_str(), testing::HasSubstr("Missed key
column: KEY"));
+ throw;
+ }
+ },
+ ignite_error);
+}
+
+TEST_F(record_view_test, wrong_mapped_value_throws) {
+ {
+ test_type val{1, "foo"};
+ view.upsert(nullptr, val);
+ }
+
+ auto table = m_client.get_tables().get_table(TABLE_1);
+ auto wrong_view = table->get_record_view<wrong_mapping_value>();
+
+ wrong_mapping_value key{1};
+ wrong_mapping_value val{1, "foo"};
+
+ // Should work just fine. Having additional field and not providing value
field is not an error.
+ wrong_view.upsert(nullptr, val);
+
+ EXPECT_THROW(
+ {
+ try {
+ (void) wrong_view.get(nullptr, key);
+ } catch (const ignite_error &e) {
+ EXPECT_EQ(e.what_str(), "Can not find column with the name
'str' in the tuple");
+ throw;
+ }
+ },
+ ignite_error);
+}
+
+TEST_F(record_view_test, upsert_get) {
+ test_type key{1};
+ test_type val{1, "foo"};
+
+ view.upsert(nullptr, val);
+ auto res = view.get(nullptr, key);
+
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(1L, res->key);
+ EXPECT_EQ("foo", res->val);
+}
+
+TEST_F(record_view_test, upsert_get_async) {
+ test_type key{1};
+ test_type val{1, "foo"};
+
+ auto all_done = std::make_shared<std::promise<std::optional<test_type>>>();
+
+ view.upsert_async(nullptr, val, [&](ignite_result<void> &&res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ view.get_async(nullptr, key, [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
+ });
+
+ auto res = all_done->get_future().get();
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(val.key, res->key);
+ EXPECT_EQ(val.val, res->val);
+}
+
+
+TEST_F(record_view_test, upsert_overrides_value) {
+ test_type key{1};
+ test_type val{1, "foo"};
+
+ view.upsert(nullptr, val);
+ auto res = view.get(nullptr, key);
+
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(1L, res->key);
+ EXPECT_EQ("foo", res->val);
+
+ val.val = "bar";
+ view.upsert(nullptr, val);
+ res = view.get(nullptr, key);
+
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(1L, res->key);
+ EXPECT_EQ("bar", res->val);
+}
+
+TEST_F(record_view_test, get_all_empty) {
+ auto res = view.get_all(nullptr, {});
+ EXPECT_TRUE(res.empty());
+}
+
+TEST_F(record_view_test, get_all_nonexisting) {
+ auto res = view.get_all(nullptr, {test_type(-42)});
+
+ ASSERT_TRUE(res.empty());
+}
+
+TEST_F(record_view_test, upsert_all_empty_no_throw) {
+ view.upsert_all(nullptr, {});
+}
+
+TEST_F(record_view_test, upsert_all_get_all) {
+ static constexpr std::size_t records_num = 10;
+
+ std::vector<test_type> records;
+ records.reserve(records_num);
+ for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i)
+ records.emplace_back(i, "Val" + std::to_string(i));
+
+ std::vector<test_type> keys;
+ for (std::int64_t i = 9; i < 13; ++i)
+ keys.emplace_back(i);
+
+ view.upsert_all(nullptr, records);
+ auto res = view.get_all(nullptr, keys);
+
+ // TODO: Key order should be preserved by the server (IGNITE-16004).
+ EXPECT_EQ(res.size(), 2);
+
+ ASSERT_TRUE(res[0].has_value());
+ EXPECT_EQ(9, res[0]->key);
+ EXPECT_EQ("Val9", res[0]->val);
+
+ ASSERT_TRUE(res[1].has_value());
+ EXPECT_EQ(10, res[1]->key);
+ EXPECT_EQ("Val10", res[1]->val);
+}
+
+TEST_F(record_view_test, upsert_all_get_all_async) {
+ static constexpr std::size_t records_num = 10;
+
+ std::vector<test_type> records;
+ records.reserve(records_num);
+ for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i)
+ records.emplace_back(i, "Val" + std::to_string(i));
+
+ std::vector<test_type> keys;
+ for (std::int64_t i = 9; i < 13; ++i)
+ keys.emplace_back(i);
+
+ auto all_done =
std::make_shared<std::promise<std::vector<std::optional<test_type>>>>();
+
+ view.upsert_all_async(nullptr, records, [&](ignite_result<void> &&res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ // TODO: Key order should be preserved by the server (IGNITE-16004).
+ view.get_all_async(nullptr, keys, [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
+ });
+
+ auto res = all_done->get_future().get();
+
+ EXPECT_EQ(res.size(), 2);
+
+ ASSERT_TRUE(res[0].has_value());
+ EXPECT_EQ(9, res[0]->key);
+ EXPECT_EQ("Val9", res[0]->val);
+
+ ASSERT_TRUE(res[1].has_value());
+ EXPECT_EQ(10, res[1]->key);
+ EXPECT_EQ("Val10", res[1]->val);
+}
+
+TEST_F(record_view_test, get_and_upsert_new_record) {
+ test_type val{42, "foo"};
+ auto res = view.get_and_upsert(nullptr, val);
+
+ ASSERT_FALSE(res.has_value());
+}
+
+TEST_F(record_view_test, get_and_upsert_existing_record) {
+ test_type val1{42, "foo"};
+ auto res = view.get_and_upsert(nullptr, val1);
+
+ ASSERT_FALSE(res.has_value());
+
+ test_type val2{42, "bar"};
+ res = view.get_and_upsert(nullptr, val2);
+
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(42, res->key);
+ EXPECT_EQ("foo", res->val);
+
+ res = view.get(nullptr, test_type(42));
+
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(42, res->key);
+ EXPECT_EQ("bar", res->val);
+}
+
+TEST_F(record_view_test, get_and_upsert_existing_record_async) {
+ test_type val1{42, "foo"};
+ test_type val2{42, "bar"};
+
+ auto first = std::make_shared<std::promise<std::optional<test_type>>>();
+
+ view.get_and_upsert_async(nullptr, val1, [&](auto res) {
+ if (!check_and_set_operation_error(*first, res))
+ return;
+
+ if (res.value().has_value())
+
first->set_exception(std::make_exception_ptr(ignite_error("Expected nullopt on
first insertion")));
+
+ view.get_and_upsert_async(
+ nullptr, val2, [&](auto res) { result_set_promise(*first,
std::move(res)); });
+ });
+
+ auto res = first->get_future().get();
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(val1.key, res->key);
+ EXPECT_EQ(val1.val, res->val);
+
+ auto second = std::make_shared<std::promise<std::optional<test_type>>>();
+ view.get_async(nullptr, test_type(42), [&](auto res) {
result_set_promise(*second, std::move(res)); });
+
+ res = second->get_future().get();
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(val2.key, res->key);
+ EXPECT_EQ(val2.val, res->val);
+}
+
+TEST_F(record_view_test, insert_new_record) {
+ test_type val{42, "foo"};
+ auto res = view.insert(nullptr, val);
+
+ ASSERT_TRUE(res);
+}
+
+TEST_F(record_view_test, insert_existing_record) {
+ test_type val1{42, "foo"};
+ auto inserted = view.insert(nullptr, val1);
+ ASSERT_TRUE(inserted);
+
+ test_type val2{42, "bar"};
+ inserted = view.insert(nullptr, val2);
+ ASSERT_FALSE(inserted);
+
+ auto res = view.get(nullptr, test_type(42));
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(42, res->key);
+ EXPECT_EQ("foo", res->val);
+}
+
+TEST_F(record_view_test, insert_existing_record_async) {
+ test_type val1{42, "foo"};
+ test_type val2{42, "bar"};
+
+ auto all_done = std::make_shared<std::promise<std::optional<test_type>>>();
+
+ view.insert_async(nullptr, val1, [&](ignite_result<bool> &&res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (!res.value())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected true on
first insertion")));
+
+ view.insert_async(nullptr, val2, [&](ignite_result<bool> &&res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (res.value())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected false on
second insertion")));
+
+ view.get_async(
+ nullptr, test_type(42), [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
+ });
+ });
+
+ auto res = all_done->get_future().get();
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(val1.key, res->key);
+ EXPECT_EQ(val1.val, res->val);
+}
+
+TEST_F(record_view_test, insert_all_new) {
+ static constexpr std::size_t records_num = 10;
+
+ std::vector<test_type> keys;
+ std::vector<test_type> records;
+ for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i) {
+ keys.emplace_back(i);
+ records.emplace_back(i, "Val" + std::to_string(i));
+ }
+
+ auto insert_res = view.insert_all(nullptr, records);
+
+ ASSERT_TRUE(insert_res.empty());
+
+ auto res = view.get_all(nullptr, keys);
+
+ EXPECT_EQ(res.size(), 10);
+ ASSERT_TRUE(std::all_of(res.begin(), res.end(), [](const auto &elem) {
return elem.has_value(); }));
+}
+
+TEST_F(record_view_test, insert_all_overlapped) {
+ auto res = view.insert_all(nullptr, {test_type(1, "foo"), test_type(2,
"bar")});
+
+ ASSERT_TRUE(res.empty());
+
+ res = view.insert_all(nullptr, {test_type(2, "baz"), test_type(3, "bar")});
+
+ EXPECT_EQ(res.size(), 1);
+ EXPECT_EQ(2, res.front().key);
+ EXPECT_EQ("baz", res.front().val);
+
+ auto res2 = view.get(nullptr, test_type(2));
+
+ ASSERT_TRUE(res2.has_value());
+ EXPECT_EQ(2, res2->key);
+ EXPECT_EQ("bar", res2->val);
+}
+
+TEST_F(record_view_test, insert_all_overlapped_async) {
+ auto all_done = std::make_shared<std::promise<std::optional<test_type>>>();
+
+ view.insert_all_async(nullptr, {test_type(1, "foo"), test_type(2, "bar")},
[&](auto res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (!res.value().empty())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected empty
return on first insertion")));
+
+ view.insert_all_async(
+ nullptr, {test_type(1, "foo"), test_type(2, "baz"), test_type(3,
"bar")}, [&](auto res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (res.value().size() != 2)
+ all_done->set_exception(std::make_exception_ptr(
+ ignite_error("Expected 2 on second insertion but got "
+ std::to_string(res.value().size()))));
+
+ view.get_async(
+ nullptr, test_type(2), [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
+ });
+ });
+
+ auto res = all_done->get_future().get();
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(2, res->key);
+ EXPECT_EQ("bar", res->val);
+}
+
+TEST_F(record_view_test, insert_all_empty) {
+ auto res = view.insert_all(nullptr, {});
+ EXPECT_TRUE(res.empty());
+}
+
+TEST_F(record_view_test, replace_nonexisting) {
+ test_type val{42, "foo"};
+ auto replaced = view.replace(nullptr, val);
+
+ ASSERT_FALSE(replaced);
+
+ auto res = view.get(nullptr, test_type(42));
+ ASSERT_FALSE(res.has_value());
+}
+
+TEST_F(record_view_test, replace_existing) {
+ test_type val1{42, "foo"};
+ auto replaced = view.insert(nullptr, val1);
+ ASSERT_TRUE(replaced);
+
+ test_type val2{42, "bar"};
+ replaced = view.replace(nullptr, val2);
+ ASSERT_TRUE(replaced);
+
+ auto res = view.get(nullptr, test_type(42));
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(42, res->key);
+ EXPECT_EQ("bar", res->val);
+}
+
+TEST_F(record_view_test, replace_existing_async) {
+ test_type val1{42, "foo"};
+ test_type val2{42, "bar"};
+
+ auto all_done = std::make_shared<std::promise<std::optional<test_type>>>();
+
+ view.insert_async(nullptr, val1, [&](ignite_result<bool> &&res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (!res.value())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected true on
insertion")));
+
+ view.replace_async(nullptr, val2, [&](ignite_result<bool> &&res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (!res.value())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected true on
replace")));
+
+ view.get_async(
+ nullptr, test_type(42), [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
+ });
+ });
+
+ auto res = all_done->get_future().get();
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(val2.key, res->key);
+ EXPECT_EQ(val2.val, res->val);
+}
+
+TEST_F(record_view_test, replace_exact_nonexisting) {
+ auto replaced = view.replace(nullptr, test_type(42, "foo"), test_type(42,
"bar"));
+
+ ASSERT_FALSE(replaced);
+
+ auto res = view.get(nullptr, test_type(42));
+ ASSERT_FALSE(res.has_value());
+}
+
+TEST_F(record_view_test, replace_exact_existing_wrong) {
+ auto inserted = view.insert(nullptr, test_type(42, "foo"));
+ ASSERT_TRUE(inserted);
+
+ auto replaced = view.replace(nullptr, test_type(42, "bar"), test_type(42,
"baz"));
+ ASSERT_FALSE(replaced);
+
+ auto res = view.get(nullptr, test_type(42));
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(42, res->key);
+ EXPECT_EQ("foo", res->val);
+}
+
+TEST_F(record_view_test, replace_exact_existing_right) {
+ auto inserted = view.insert(nullptr, test_type(42, "foo"));
+ ASSERT_TRUE(inserted);
+
+ auto replaced = view.replace(nullptr, test_type(42, "foo"), test_type(42,
"baz"));
+ ASSERT_TRUE(replaced);
+
+ auto res = view.get(nullptr, test_type(42));
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(42, res->key);
+ EXPECT_EQ("baz", res->val);
+}
+
+TEST_F(record_view_test, replace_exact_existing_right_async) {
+ test_type val1{42, "foo"};
+ test_type val2{42, "bar"};
+
+ auto all_done = std::make_shared<std::promise<std::optional<test_type>>>();
+
+ view.insert_async(nullptr, val1, [&](ignite_result<bool> &&res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (!res.value())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected true on
insertion")));
+
+ view.replace_async(nullptr, val1, val2, [&](ignite_result<bool> &&res)
{
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (!res.value())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected true on
replace")));
+
+ view.get_async(
+ nullptr, test_type(42), [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
+ });
+ });
+
+ auto res = all_done->get_future().get();
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(val2.key, res->key);
+ EXPECT_EQ(val2.val, res->val);
+}
+
+TEST_F(record_view_test, get_and_replace_nonexisting) {
+ test_type val{42, "foo"};
+ auto res1 = view.get_and_replace(nullptr, val);
+
+ ASSERT_FALSE(res1.has_value());
+
+ auto res2 = view.get(nullptr, test_type(42));
+ ASSERT_FALSE(res2.has_value());
+}
+
+TEST_F(record_view_test, get_and_replace_existing) {
+ test_type val1{42, "foo"};
+ auto inserted = view.insert(nullptr, val1);
+ ASSERT_TRUE(inserted);
+
+ test_type val2{42, "bar"};
+ auto res = view.get_and_replace(nullptr, val2);
+
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(42, res->key);
+ EXPECT_EQ("foo", res->val);
+
+ res = view.get(nullptr, test_type(42));
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(42, res->key);
+ EXPECT_EQ("bar", res->val);
+}
+
+TEST_F(record_view_test, get_and_replace_existing_async) {
+ test_type val1{42, "foo"};
+ test_type val2{42, "bar"};
+
+ auto all_done = std::make_shared<std::promise<std::optional<test_type>>>();
+
+ view.insert_async(nullptr, val1, [&](ignite_result<bool> &&res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (!res.value())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected true on
insertion")));
+
+ view.get_and_replace_async(
+ nullptr, val2, [&](auto res) { result_set_promise(*all_done,
std::move(res)); });
+ });
+
+ auto res = all_done->get_future().get();
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(val1.key, res->key);
+ EXPECT_EQ(val1.val, res->val);
+}
+
+TEST_F(record_view_test, remove_nonexisting) {
+ auto removed = view.remove(nullptr, test_type(1));
+ ASSERT_FALSE(removed);
+
+ auto res = view.get(nullptr, test_type(1));
+ ASSERT_FALSE(res.has_value());
+}
+
+TEST_F(record_view_test, remove_existing) {
+ auto inserted = view.insert(nullptr, test_type(1, "foo"));
+ ASSERT_TRUE(inserted);
+
+ auto removed = view.remove(nullptr, test_type(1));
+ ASSERT_TRUE(removed);
+
+ auto res = view.get(nullptr, test_type(1));
+ ASSERT_FALSE(res.has_value());
+}
+
+TEST_F(record_view_test, remove_existing_async) {
+ auto all_done = std::make_shared<std::promise<bool>>();
+
+ view.insert_async(nullptr, test_type(42, "foo"), [&](ignite_result<bool>
&&res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (!res.value())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected true on
insertion")));
+
+ view.remove_async(
+ nullptr, test_type(42), [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
+ });
+
+ auto res = all_done->get_future().get();
+ ASSERT_TRUE(res);
+}
+
+TEST_F(record_view_test, remove_exact_nonexisting) {
+ auto res = view.remove_exact(nullptr, test_type(1, "foo"));
+ ASSERT_FALSE(res);
+}
+
+TEST_F(record_view_test, remove_exact_existing) {
+ auto inserted = view.insert(nullptr, test_type(1, "foo"));
+ ASSERT_TRUE(inserted);
+
+ auto removed = view.remove_exact(nullptr, test_type(1));
+ ASSERT_FALSE(removed);
+
+ removed = view.remove_exact(nullptr, test_type(1, "bar"));
+ ASSERT_FALSE(removed);
+
+ removed = view.remove_exact(nullptr, test_type(1, "foo"));
+ ASSERT_TRUE(removed);
+
+ auto res = view.get(nullptr, test_type(1));
+ ASSERT_FALSE(res.has_value());
+}
+
+TEST_F(record_view_test, remove_exact_existing_async) {
+ test_type val{42, "foo"};
+
+ auto all_done = std::make_shared<std::promise<bool>>();
+
+ auto inserted = view.insert(nullptr, val);
+ ASSERT_TRUE(inserted);
+
+ view.remove_exact_async(nullptr, test_type(42), [&](auto res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (res.value())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected false on
first remove")));
+
+ view.remove_exact_async(nullptr, test_type(42, "bar"), [&](auto res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (res.value())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected false on
second remove")));
+
+ view.remove_exact_async(
+ nullptr, val, [&](auto res) { result_set_promise(*all_done,
std::move(res)); });
+ });
+ });
+
+ auto res = all_done->get_future().get();
+ ASSERT_TRUE(res);
+}
+
+TEST_F(record_view_test, get_and_remove_nonexisting) {
+ auto removed = view.get_and_remove(nullptr, test_type(42, "foo"));
+ ASSERT_FALSE(removed.has_value());
+
+ auto res = view.get(nullptr, test_type(42));
+ ASSERT_FALSE(res.has_value());
+}
+
+TEST_F(record_view_test, get_and_remove_existing) {
+ auto inserted = view.insert(nullptr, test_type(42, "foo"));
+ ASSERT_TRUE(inserted);
+
+ auto removed = view.get_and_remove(nullptr, test_type(42));
+
+ ASSERT_TRUE(removed.has_value());
+ EXPECT_EQ(42, removed->key);
+ EXPECT_EQ("foo", removed->val);
+
+ auto res = view.get(nullptr, test_type(42));
+ ASSERT_FALSE(res.has_value());
+}
+
+TEST_F(record_view_test, get_and_remove_existing_async) {
+ test_type val1{42, "foo"};
+
+ auto all_done = std::make_shared<std::promise<std::optional<test_type>>>();
+
+ view.insert_async(nullptr, val1, [&](ignite_result<bool> &&res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (!res.value())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected true on
insertion")));
+
+ view.get_and_remove_async(
+ nullptr, test_type(42), [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
+ });
+
+ auto res = all_done->get_future().get();
+ ASSERT_TRUE(res.has_value());
+ EXPECT_EQ(val1.key, res->key);
+ EXPECT_EQ(val1.val, res->val);
+}
+
+TEST_F(record_view_test, remove_all_nonexisting_keys_return_all) {
+ std::vector<test_type> non_existing = {test_type(1), test_type(2)};
+ auto res = view.remove_all(nullptr, non_existing);
+
+ EXPECT_EQ(res.size(), 2);
+
+ // TODO: Key order should be preserved by the server (IGNITE-16004).
+ EXPECT_EQ(2, res[0].key);
+ EXPECT_EQ(1, res[1].key);
+}
+
+TEST_F(record_view_test, remove_all_only_existing) {
+ std::vector<test_type> to_insert = {test_type(1, "foo"), test_type(2,
"bar")};
+ view.upsert_all(nullptr, to_insert);
+
+ auto res = view.remove_all(nullptr, {test_type(1), test_type(2)});
+
+ EXPECT_TRUE(res.empty());
+}
+
+TEST_F(record_view_test, remove_all_overlapped) {
+ static constexpr std::size_t records_num = 10;
+
+ std::vector<test_type> to_insert;
+ to_insert.reserve(records_num);
+ for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i)
+ to_insert.emplace_back(i, "Val" + std::to_string(i));
+
+ view.upsert_all(nullptr, to_insert);
+
+ std::vector<test_type> to_remove;
+ for (std::int64_t i = 9; i < 13; ++i)
+ to_remove.emplace_back(i);
+
+ auto res = view.remove_all(nullptr, to_remove);
+
+ EXPECT_EQ(res.size(), 2);
+
+ // TODO: Key order should be preserved by the server (IGNITE-16004).
+ EXPECT_EQ(12, res[0].key);
+ EXPECT_EQ(11, res[1].key);
+}
+
+TEST_F(record_view_test, remove_all_empty) {
+ auto res = view.remove_all(nullptr, {});
+ EXPECT_TRUE(res.empty());
+}
+
+TEST_F(record_view_test, remove_all_exact_nonexisting) {
+ auto res = view.remove_all_exact(nullptr, {test_type(1, "foo"),
test_type(2, "bar")});
+
+ // TODO: Key order should be preserved by the server (IGNITE-16004).
+ ASSERT_EQ(2, res.size());
+}
+
+TEST_F(record_view_test, remove_all_exact_overlapped) {
+ auto res = view.insert_all(nullptr, {test_type(1, "foo"), test_type(2,
"bar")});
+
+ ASSERT_TRUE(res.empty());
+
+ res = view.remove_all_exact(nullptr, {test_type(1, "baz"), test_type(2,
"bar")});
+
+ EXPECT_EQ(res.size(), 1);
+ EXPECT_EQ(1, res.front().key);
+ EXPECT_EQ("baz", res.front().val);
+
+ auto res2 = view.get(nullptr, test_type(2));
+
+ ASSERT_FALSE(res2.has_value());
+}
+
+TEST_F(record_view_test, remove_all_exact_overlapped_async) {
+ auto all_done = std::make_shared<std::promise<std::vector<test_type>>>();
+
+ view.insert_all_async(nullptr, {test_type(1, "foo"), test_type(2, "bar")},
[&](auto res) {
+ if (!check_and_set_operation_error(*all_done, res))
+ return;
+
+ if (!res.value().empty())
+
all_done->set_exception(std::make_exception_ptr(ignite_error("Expected empty
return on first insertion")));
+
+ view.remove_all_exact_async(nullptr, {test_type(1, "baz"),
test_type(2, "bar")},
+ [&](auto res) { result_set_promise(*all_done, std::move(res)); });
+ });
+
+ auto res = all_done->get_future().get();
+ EXPECT_EQ(res.size(), 1);
+ EXPECT_EQ(1, res.front().key);
+ EXPECT_EQ("baz", res.front().val);
+}
+
+TEST_F(record_view_test, remove_all_exact_empty) {
+ auto res = view.remove_all_exact(nullptr, {});
+ EXPECT_TRUE(res.empty());
+}
+
+/**
+ * All columns type table mapping (@see
ignite_runner_suite::TABLE_NAME_ALL_COLUMNS).
+ */
+struct all_fields_type {
+ all_fields_type() = default;
+ explicit all_fields_type(std::int64_t key) : m_key(key) {}
+
+ std::int64_t m_key{0};
+ std::string m_str;
+ std::int8_t m_int8{0};
+ std::int16_t m_int16{0};
+ std::int32_t m_int32{0};
+ std::int64_t m_int64{0};
+ float m_float{.0f};
+ double m_double{.0};
+ uuid m_uuid;
+ ignite_date m_date;
+ bit_array m_bitmask;
+ ignite_time m_time;
+ ignite_time m_time2;
+ ignite_date_time m_datetime;
+ ignite_date_time m_datetime2;
+ ignite_timestamp m_timestamp;
+ ignite_timestamp m_timestamp2;
+ std::vector<std::byte> m_blob;
+ big_decimal m_decimal;
+};
+
+namespace ignite {
+
+template<>
+ignite_tuple convert_to_tuple(all_fields_type &&value) {
+ ignite_tuple tuple;
+
+ tuple.set("key", value.m_key);
+ tuple.set("str", value.m_str);
+ tuple.set("int8", value.m_int8);
+ tuple.set("int16", value.m_int16);
+ tuple.set("int32", value.m_int32);
+ tuple.set("int64", value.m_int64);
+ tuple.set("float", value.m_float);
+ tuple.set("double", value.m_double);
+ tuple.set("uuid", value.m_uuid);
+ tuple.set("date", value.m_date);
+ tuple.set("bitmask", value.m_bitmask);
+ tuple.set("time", value.m_time);
+ tuple.set("time2", value.m_time2);
+ tuple.set("datetime", value.m_datetime);
+ tuple.set("datetime2", value.m_datetime2);
+ tuple.set("timestamp", value.m_timestamp);
+ tuple.set("timestamp2", value.m_timestamp2);
+ tuple.set("blob", value.m_blob);
+ tuple.set("decimal", value.m_decimal);
+
+ return tuple;
+}
+
+template<>
+all_fields_type convert_from_tuple(ignite_tuple&& value) {
+ all_fields_type res;
+
+ res.m_key = value.get<std::int64_t>("key");
+
+ if (value.column_count() > 1) {
+ res.m_str = value.get<std::string>("str");
+ res.m_int8 = value.get<std::int8_t>("int8");
+ res.m_int16 = value.get<std::int16_t>("int16");
+ res.m_int32 = value.get<std::int32_t>("int32");
+ res.m_int64 = value.get<std::int64_t>("int64");
+ res.m_float = value.get<float>("float");
+ res.m_double = value.get<double>("double");
+ res.m_uuid = value.get<uuid>("uuid");
+ res.m_date = value.get<ignite_date>("date");
+ res.m_bitmask = value.get<bit_array>("bitmask");
+ res.m_time = value.get<ignite_time>("time");
+ res.m_time2 = value.get<ignite_time>("time2");
+ res.m_datetime = value.get<ignite_date_time>("datetime");
+ res.m_datetime2 = value.get<ignite_date_time>("datetime2");
+ res.m_timestamp = value.get<ignite_timestamp>("timestamp");
+ res.m_timestamp2 = value.get<ignite_timestamp>("timestamp2");
+ res.m_blob = value.get<std::vector<std::byte>>("blob");
+ res.m_decimal = value.get<big_decimal>("decimal");
+ }
+
+ return res;
+}
+
+}
+
+TEST_F(record_view_test, types_test) {
+ auto table = m_client.get_tables().get_table(TABLE_NAME_ALL_COLUMNS);
+ auto view2 = table->get_record_view<all_fields_type>();
+
+ all_fields_type inserted;
+ inserted.m_key = 42;
+ inserted.m_str = "test";
+ inserted.m_int8 = 1;
+ inserted.m_int16 = 2;
+ inserted.m_int32 = 3;
+ inserted.m_int64 = 4;
+ inserted.m_float = .5f;
+ inserted.m_double = .6f;
+ inserted.m_uuid = {0x123e4567e89b12d3, 0x7456426614174000};
+ inserted.m_date = {2023, 2, 7};
+ inserted.m_bitmask = bit_array{16, true};
+ inserted.m_time = {17, 4, 12, 3543634};
+ inserted.m_time2 = {17, 4, 12, 3543634};
+ inserted.m_datetime = {{2020, 7, 28}, {2, 15, 52, 6349879}};
+ inserted.m_datetime2 = {{2020, 7, 28}, {2, 15, 52, 6349879}};
+ inserted.m_timestamp = {3875238472, 248760634};
+ inserted.m_timestamp2 = {3875238472, 248760634};
+ inserted.m_blob = {std::byte(1), std::byte(2), std::byte(42)};
+ inserted.m_decimal = big_decimal{123456789098765};
+
+ view2.upsert(nullptr, inserted);
+ auto res = view2.get(nullptr, all_fields_type{42});
+
+ ASSERT_TRUE(res.has_value());
+
+ EXPECT_EQ(inserted.m_key, res->m_key);
+ EXPECT_EQ(inserted.m_str, res->m_str);
+ EXPECT_EQ(inserted.m_int8, res->m_int8);
+ EXPECT_EQ(inserted.m_int16, res->m_int16);
+ EXPECT_EQ(inserted.m_int32, res->m_int32);
+ EXPECT_EQ(inserted.m_int64, res->m_int64);
+ EXPECT_EQ(inserted.m_float, res->m_float);
+ EXPECT_EQ(inserted.m_double, res->m_double);
+ EXPECT_EQ(inserted.m_uuid, res->m_uuid);
+ EXPECT_EQ(inserted.m_date, res->m_date);
+ EXPECT_EQ(inserted.m_bitmask, res->m_bitmask);
+ EXPECT_EQ(inserted.m_time, res->m_time);
+ EXPECT_EQ(inserted.m_datetime, res->m_datetime);
+ EXPECT_EQ(inserted.m_timestamp, res->m_timestamp);
+ EXPECT_EQ(inserted.m_blob, res->m_blob);
+ EXPECT_EQ(inserted.m_decimal, res->m_decimal);
+
+ EXPECT_EQ(ignite_time(17, 4, 12), res->m_time2);
+ EXPECT_EQ(ignite_date_time({2020, 7, 28}, {2, 15, 52, 6000000}),
res->m_datetime2);
+ EXPECT_EQ(ignite_timestamp(3875238472, 248700000), res->m_timestamp2);
+}
+
diff --git a/modules/platforms/cpp/tests/client-test/tables_test.cpp
b/modules/platforms/cpp/tests/client-test/tables_test.cpp
index a56d562fa4..73cf73404d 100644
--- a/modules/platforms/cpp/tests/client-test/tables_test.cpp
+++ b/modules/platforms/cpp/tests/client-test/tables_test.cpp
@@ -45,7 +45,7 @@ TEST_F(tables_test, tables_get_table) {
auto table = tables.get_table("tbl1");
ASSERT_TRUE(table.has_value());
- EXPECT_EQ(table->name(), "tbl1");
+ EXPECT_EQ(table->get_name(), "tbl1");
}
TEST_F(tables_test, tables_get_table_async_promises) {
@@ -70,7 +70,7 @@ TEST_F(tables_test, tables_get_table_async_promises) {
auto table = tablePromise->get_future().get();
ASSERT_TRUE(table.has_value());
- EXPECT_EQ(table->name(), "tbl1");
+ EXPECT_EQ(table->get_name(), "tbl1");
}
TEST_F(tables_test, tables_get_table_async_callbacks) {
@@ -113,9 +113,9 @@ TEST_F(tables_test, tables_get_table_async_callbacks) {
operation2->set_exception(std::make_exception_ptr(ignite_error("Table should
not be null")));
return;
}
- if (table->name() != "tbl1") {
+ if (table->get_name() != "tbl1") {
operation2->set_exception(
- std::make_exception_ptr(ignite_error("Table has unexpected
name: " + table->name())));
+ std::make_exception_ptr(ignite_error("Table has unexpected
name: " + table->get_name())));
return;
}
@@ -140,7 +140,7 @@ TEST_F(tables_test, tables_get_tables) {
auto tables = tablesApi.get_tables();
ASSERT_GT(tables.size(), 0);
- auto it = std::find_if(tables.begin(), tables.end(), [](auto &table) {
return table.name() == "TBL1"; });
+ auto it = std::find_if(tables.begin(), tables.end(), [](auto &table) {
return table.get_name() == "TBL1"; });
ASSERT_NE(it, tables.end());
}
@@ -159,7 +159,7 @@ TEST_F(tables_test, tables_get_tables_async_promises) {
auto tables = tablesPromise->get_future().get();
ASSERT_GT(tables.size(), 0);
- auto it = std::find_if(tables.begin(), tables.end(), [](auto &table) {
return table.name() == "TBL1"; });
+ auto it = std::find_if(tables.begin(), tables.end(), [](auto &table) {
return table.get_name() == "TBL1"; });
ASSERT_NE(it, tables.end());
}
diff --git a/modules/platforms/cpp/tests/client-test/transactions_test.cpp
b/modules/platforms/cpp/tests/client-test/transactions_test.cpp
index 135d52d1bc..9b70c4b012 100644
--- a/modules/platforms/cpp/tests/client-test/transactions_test.cpp
+++ b/modules/platforms/cpp/tests/client-test/transactions_test.cpp
@@ -68,7 +68,7 @@ TEST_F(transactions_test, empty_transaction_commit) {
}
TEST_F(transactions_test, commit_updates_data) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -86,7 +86,7 @@ TEST_F(transactions_test, commit_updates_data) {
}
TEST_F(transactions_test, rollback_does_not_update_data) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -101,7 +101,7 @@ TEST_F(transactions_test, rollback_does_not_update_data) {
}
TEST_F(transactions_test, destruction_does_not_update_data) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
{
auto tx = m_client.get_transactions().begin();
@@ -116,7 +116,7 @@ TEST_F(transactions_test, destruction_does_not_update_data)
{
}
TEST_F(transactions_test, non_committed_data_visible_for_tx) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -132,7 +132,7 @@ TEST_F(transactions_test,
non_committed_data_visible_for_tx) {
}
TEST_F(transactions_test, sql_commit) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -150,7 +150,7 @@ TEST_F(transactions_test, sql_commit) {
}
TEST_F(transactions_test, sql_rollback) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -193,7 +193,7 @@ TEST_F(transactions_test, rollback_after_rollback_works) {
}
TEST_F(transactions_test, record_view_upsert_all) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -215,7 +215,7 @@ TEST_F(transactions_test, record_view_upsert_all) {
}
TEST_F(transactions_test, record_view_get_and_upsert) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -239,7 +239,7 @@ TEST_F(transactions_test, record_view_get_and_upsert) {
}
TEST_F(transactions_test, record_view_insert) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -261,7 +261,7 @@ TEST_F(transactions_test, record_view_insert) {
}
TEST_F(transactions_test, record_view_insert_all) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -283,7 +283,7 @@ TEST_F(transactions_test, record_view_insert_all) {
}
TEST_F(transactions_test, record_view_replace) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -302,7 +302,7 @@ TEST_F(transactions_test, record_view_replace) {
}
TEST_F(transactions_test, record_view_replace_exact) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -321,7 +321,7 @@ TEST_F(transactions_test, record_view_replace_exact) {
}
TEST_F(transactions_test, record_view_get_and_replace) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto tx = m_client.get_transactions().begin();
@@ -343,7 +343,7 @@ TEST_F(transactions_test, record_view_get_and_replace) {
}
TEST_F(transactions_test, record_view_remove) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto value0 = get_tuple(42, "Lorem ipsum");
record_view.insert(nullptr, value0);
@@ -359,7 +359,7 @@ TEST_F(transactions_test, record_view_remove) {
}
TEST_F(transactions_test, record_view_remove_exact) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto value0 = get_tuple(42, "Lorem ipsum");
record_view.insert(nullptr, value0);
@@ -375,7 +375,7 @@ TEST_F(transactions_test, record_view_remove_exact) {
}
TEST_F(transactions_test, record_view_get_and_remove) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto value0 = get_tuple(42, "Lorem ipsum");
record_view.insert(nullptr, value0);
@@ -399,7 +399,7 @@ TEST_F(transactions_test, record_view_get_and_remove) {
}
TEST_F(transactions_test, record_view_remove_all) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto value0 = get_tuple(42, "Lorem ipsum");
record_view.insert(nullptr, value0);
@@ -415,7 +415,7 @@ TEST_F(transactions_test, record_view_remove_all) {
}
TEST_F(transactions_test, record_view_remove_all_exact) {
- auto record_view =
m_client.get_tables().get_table("tbl1")->record_binary_view();
+ auto record_view =
m_client.get_tables().get_table("tbl1")->get_record_binary_view();
auto value0 = get_tuple(42, "Lorem ipsum");
record_view.insert(nullptr, value0);