caosdb/transaction.h

Defines

ASSERT_CAN_ADD_RETRIEVAL

Do all necessary checks and assure that another retrieval (by id or by query) can be added as a sub-request to a transaction.

ASSERT_CAN_ADD_QUERY

Do all necessary checks and assure that another retrieval (by id or by query) can be added as a sub-request to a transaction.

ASSERT_CAN_ADD_DELETION

Do all necessary checks and assure that another deletion can be added as a sub-request to a transaction.

ASSERT_CAN_ADD_INSERTION

Do all necessary checks and assure that another insertion can be added as a sub-request to a transaction.

ASSERT_CAN_ADD_UPDATE

Do all necessary checks and assure that another update can be added as a sub-request to a transaction.

namespace caosdb
namespace transaction

Creation and execution of transactions.

Author

Timm Fitschen

Date

2021-08-05

Typedefs

using RetrieveResponse = caosdb::entity::v1::RetrieveResponse
using TransactionResponseCase = caosdb::entity::v1::TransactionResponse::TransactionResponseCase
class ResultSet
#include <transaction.h>

Abstract base class for the results of a Transaction.

Subclassed by caosdb::transaction::AbstractMultiResultSet

Public Functions

virtual ~ResultSet() = default
virtual auto size() const noexcept -> int = 0
virtual auto at(const int index) const -> const Entity& = 0
virtual auto mutable_at(int index) const -> Entity* = 0
virtual auto release_at(int index) -> Entity* = 0

Return the Entity at the given index.

This method releases the entity from the underlying collection and thus leaves the ResultSet in a corrupted state.

This method can be called only once for each index.

auto begin() const -> iterator
auto end() const -> iterator
class iterator : public std::iterator<std::output_iterator_tag, Entity>

Public Functions

explicit iterator(const ResultSet *result_set, int index = 0)
auto operator*() const -> const Entity&
auto operator++() -> iterator&
auto operator++(int) -> iterator
auto operator!=(const iterator &rhs) const -> bool

Private Members

int current_index = 0
const ResultSet *result_set
class AbstractMultiResultSet : public caosdb::transaction::ResultSet

Subclassed by caosdb::transaction::MultiResultSet

Public Functions

inline AbstractMultiResultSet(const AbstractMultiResultSet &original)

Copy Constructor.

Copies the underlying collection of entities.

virtual ~AbstractMultiResultSet() = default
inline explicit AbstractMultiResultSet(std::vector<std::unique_ptr<Entity>> result_set)
inline virtual auto size() const noexcept -> int override
inline virtual auto at(const int index) const -> const Entity& override
inline virtual auto mutable_at(int index) const -> Entity* override
inline virtual auto release_at(int index) -> Entity* override

Return the Entity at the given index.

This method releases the entity from the underlying collection and thus leaves the ResultSet in a corrupted state.

This method can be called only once for each index.

inline auto clear() noexcept -> void

Remove all entities from this result set.

Protected Attributes

std::vector<std::unique_ptr<Entity>> items
class MultiResultSet : public caosdb::transaction::AbstractMultiResultSet
#include <transaction.h>

Container with results of a transaction.

Public Functions

~MultiResultSet() = default
explicit MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set)
class Transaction
#include <transaction.h>

Create a transaction via CaosDBConnection.createTransaction()

Public Types

enum TransactionType

The transaction type restricts the kind of sub-transaction which may be added to a transaction (insertion, update, deletion, retrieval).

Note

MIXED_READ_AND_WRITE and MIXED_WRITE transaction are not supported yet.

Values:

enumerator NONE

Unspecified or not specified yet.

enumerator READ_ONLY

Only retrievals (by id, by query)

enumerator INSERT_ONLY

Only insertions.

enumerator UPDATE_ONLY

Only updates.

enumerator DELETE_ONLY

Only deletions.

enumerator MIXED_WRITE

Only insertions, deletions, updates.

enumerator MIXED_READ_AND_WRITE

all kind of transaction.

Public Functions

Transaction(std::shared_ptr<EntityTransactionService::Stub> entity_service, std::shared_ptr<FileTransmissionService::Stub> file_service)
~Transaction()
Transaction(const Transaction&) = delete
Transaction &operator=(const Transaction&) = delete
Transaction(Transaction&&) = delete
Transaction &operator=(Transaction&&) = delete
auto RetrieveAndDownloadFileById(const std::string &id, const std::string &local_path) noexcept -> StatusCode

Add an entity id to this transaction for retrieval and also download the file.

If the entity doesn’t have a file a warning is appended.

If the file cannot be downloaded due to unsufficient permissions an error is appended.

auto RetrieveById(const std::string &id) noexcept -> StatusCode

Add an entity id to this transaction for retrieval.

The retrieval is being processed when the Execute() or ExecuteAsynchronously() methods of this transaction are called.

template<class InputIterator>
inline auto RetrieveById(InputIterator begin, InputIterator end) noexcept -> StatusCode

Add all entity ids to this transaction for retrieval.

auto Query(const std::string &query) noexcept -> StatusCode

Add a query to this transaction.

Currently, only FIND and COUNT queries are supported.

auto InsertEntity(Entity *entity) noexcept -> StatusCode

Add the entity to this transaction for an insertion.

The insertion is being processed when the Execute() or ExecuteAsynchronously() methods of this transaction are called.

Changing the entity afterwards results in undefined behavior.

auto UpdateEntity(Entity *entity) noexcept -> StatusCode

Add the entity to this transaction for an update.

The update is being processed when the Execute() or ExecuteAsynchronously() methods of this transaction are called.

Changing the entity afterwards results in undefined behavior.

auto DeleteById(const std::string &id) noexcept -> StatusCode

Add an entity id to this transaction for deletion.

The deletion is being processed when the Execute() or ExecuteAsynchronously() methods of this transaction are called.

auto Execute() -> TransactionStatus

Execute this transaction in blocking mode and return the status.

auto ExecuteAsynchronously() noexcept -> StatusCode

Execute this transaction in non-blocking mode and return immediately.

A client may request the current status at any time via GetStatus().

Use WaitForIt() to join the back-ground execution of this transaction.

auto WaitForIt() const noexcept -> TransactionStatus

Join the background execution and return the status when the execution terminates.

Use this after ExecuteAsynchronously(), otherwise the TransactionStatus still remains EXECUTING.

inline auto GetStatus() const noexcept -> TransactionStatus

Return the current status of the transaction.

inline auto GetResultSet() const noexcept -> const ResultSet&

Return the ResultSet of this transaction.

Note: If this method is called before the transaction has terminated successfully (as indicated by GetStatus().GetCode == 0) this method has undefined behavior.

inline auto ReleaseResultSet() noexcept -> const ResultSet*

Return the ResultSet of this transaction.

This method releases the ResultSet from the transaction leaving it in a currupted state.

This method can be called only once and only after the transaction has terminated.

Otherwise, this method has undefined behavior.

inline auto GetCountResult() const noexcept -> long

Return the result of a count query

Only meaningful if there was exactly one COUNT query executed in this transaction. In all other cases, the return value will be -1.

inline auto GetRequestCount() const -> int

Return the number of sub-requests in this transaction.

This is meant for debugging because the number of sub-requests is a GRPC-API detail.

inline auto ResponseToString() const -> const std::string

Get a JSON representation of the response.

For debugging.

inline auto RequestToString() const -> const std::string

Get a JSON representation of the request.

For debugging.

inline auto GetUploadFiles() const -> const std::vector<FileDescriptor>&

Return the vector which holds all the files which are to be uploaded.

auto Cancel() -> void

Cancel this transaction after it has been started with ExecuteAsynchronously().

This will cancel any active handler and drains the completion_queue.

Protected Functions

auto ProcessCalls() -> TransactionStatus

Await and process the current handler’s results.

This implies consecutive calls to the handler’s OnNext function.

inline auto GetArena() const -> Arena*

Return the Arena where this transaction may create Message instances.

Currently, this implementation is only a call to caosdb::utility::get_arena(), but in the future we might want to have a smarter memory management.

Private Functions

auto ProcessTerminated() const noexcept -> void

Await and process the termination of this transaction.

To be called at the end of DoExecuteTransaction on success.

auto ProcessRetrieveResponse(RetrieveResponse *retrieve_response, std::vector<std::unique_ptr<Entity>> *entities, bool *set_error) const noexcept -> std::unique_ptr<Entity>
auto DoExecuteTransaction() noexcept -> void

This functions actually does all the work. Also, it is the one which is going to be send to the background thread by ExecuteAsynchronously.

Private Members

mutable std::mutex transaction_mutex
mutable std::future<void> transaction_future
grpc::CompletionQueue completion_queue
std::unique_ptr<HandlerInterface> handler_
std::vector<FileDescriptor> upload_files
std::map<std::string, FileDescriptor> download_files
bool has_query = false
TransactionType transaction_type = TransactionType::NONE
mutable TransactionStatus status = TransactionStatus::INITIAL()
std::shared_ptr<EntityTransactionService::Stub> entity_service
std::shared_ptr<FileTransmissionService::Stub> file_service
MultiTransactionRequest *request
mutable MultiTransactionResponse *response
std::string error_message
mutable long query_count
mutable std::unique_ptr<ResultSet> result_set