linkahead/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 linkahead
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 Transaction
#include <transaction.h>

Create a transaction via LinkAheadConnection.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 GetResultTable() const noexcept -> const ResultTable&

Return the ResultTable of a SELECT query.

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 linkahead::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
mutable std::unique_ptr<ResultTable> result_table