/** * * TransactionImpl.h * An Tao * * Copyright 2018, An Tao. All rights reserved. * https://github.com/an-tao/drogon * Use of this source code is governed by a MIT license * that can be found in the License file. * * Drogon * */ #pragma once #include "DbConnection.h" #include #include #include namespace drogon { namespace orm { class TransactionImpl : public Transaction, public std::enable_shared_from_this { public: TransactionImpl(ClientType type, const DbConnectionPtr &connPtr, std::function commitCallback, std::function usedUpCallback); ~TransactionImpl() override; void rollback() override; void setCommitCallback( const std::function &commitCallback) override { commitCallback_ = commitCallback; } bool hasAvailableConnections() const noexcept override { return connectionPtr_->status() == ConnectStatus::Ok; } void setTimeout(double timeout) override { timeout_ = timeout; } private: DbConnectionPtr connectionPtr_; void execSql(const char *sql, size_t sqlLength, size_t paraNum, std::vector &¶meters, std::vector &&length, std::vector &&format, ResultCallback &&rcb, std::function &&exceptCallback) override { if (loop_->isInLoopThread()) { execSqlInLoop(std::string_view{sql, sqlLength}, paraNum, std::move(parameters), std::move(length), std::move(format), std::move(rcb), std::move(exceptCallback)); } else { loop_->queueInLoop( [thisPtr = shared_from_this(), sql = std::string_view{sql, sqlLength}, paraNum, parameters = std::move(parameters), length = std::move(length), format = std::move(format), rcb = std::move(rcb), exceptCallback = std::move(exceptCallback)]() mutable { thisPtr->execSqlInLoop(std::move(sql), paraNum, std::move(parameters), std::move(length), std::move(format), std::move(rcb), std::move(exceptCallback)); }); } } void execSqlInLoop( std::string_view &&sql, size_t paraNum, std::vector &¶meters, std::vector &&length, std::vector &&format, ResultCallback &&rcb, std::function &&exceptCallback); void execSqlInLoopWithTimeout( std::string_view &&sql, size_t paraNum, std::vector &¶meters, std::vector &&length, std::vector &&format, ResultCallback &&rcb, std::function &&exceptCallback); std::shared_ptr newTransaction( const std::function &) noexcept(false) override { return shared_from_this(); } void newTransactionAsync( const std::function &)> &callback) override { callback(shared_from_this()); } std::function usedUpCallback_; bool isCommitedOrRolledback_{false}; bool isWorking_{false}; void execNewTask(); struct SqlCmd { std::string_view sql_; size_t parametersNumber_; std::vector parameters_; std::vector lengths_; std::vector formats_; QueryCallback callback_; ExceptPtrCallback exceptionCallback_; bool isRollbackCmd_{false}; std::shared_ptr thisPtr_; }; using SqlCmdPtr = std::shared_ptr; std::list sqlCmdBuffer_; // std::mutex _bufferMutex; friend class DbClientImpl; friend class DbClientLockFree; void doBegin(); trantor::EventLoop *loop_; std::function commitCallback_; std::shared_ptr thisPtr_; double timeout_{-1.0}; }; } // namespace orm } // namespace drogon