17#include <drogon/exports.h>
21#include <drogon/orm/ResultIterator.h>
23#include <drogon/orm/RowIterator.h>
29#include <trantor/utils/Logger.h>
30#include <trantor/utils/NonCopyable.h>
32#ifdef __cpp_impl_coroutine
40using ResultCallback = std::function<void(
const Result &)>;
57#ifdef __cpp_impl_coroutine
60 explicit SqlAwaiter(internal::SqlBinder &&binder)
61 : binder_(std::move(binder))
65 void await_suspend(std::coroutine_handle<> handle)
71 binder_ >> [handle,
this](
const std::exception_ptr &e) {
79 internal::SqlBinder binder_;
82struct [[nodiscard]] TransactionAwaiter
83 :
public CallbackAwaiter<std::shared_ptr<Transaction> >
85 explicit TransactionAwaiter(
87 TransactionType transType = TransactionType::Deferred)
88 : client_(client), transType_(transType)
92 void await_suspend(std::coroutine_handle<> handle);
104class DROGON_EXPORT
DbClient :
public trantor::NonCopyable
134 static std::shared_ptr<DbClient>
newPgClient(
const std::string &connInfo,
136 bool autoBatch =
false);
137 static std::shared_ptr<DbClient> newMysqlClient(
const std::string &connInfo,
139 static std::shared_ptr<DbClient> newSqlite3Client(
140 const std::string &connInfo,
171 template <
typename FUNCTION1,
typename FUNCTION2,
typename... Arguments>
173 FUNCTION1 &&rCallback,
174 FUNCTION2 &&exceptCallback,
175 Arguments &&...args)
noexcept
177 auto binder = *
this << sql;
178 (void)std::initializer_list<int>{
179 (binder << std::forward<Arguments>(args), 0)...};
180 binder >> std::forward<FUNCTION1>(rCallback);
181 binder >> std::forward<FUNCTION2>(exceptCallback);
185 template <
typename... Arguments>
187 Arguments &&...args)
noexcept
189 auto binder = *
this << sql;
190 (void)std::initializer_list<int>{
191 (binder << std::forward<Arguments>(args), 0)...};
192 std::shared_ptr<std::promise<Result> > prom =
193 std::make_shared<std::promise<Result> >();
194 binder >> [prom](
const Result &r) { prom->set_value(r); };
196 [prom](
const std::exception_ptr &e) { prom->set_exception(e); };
198 return prom->get_future();
202 template <
typename... Arguments>
203 Result execSqlSync(
const std::string &sql,
204 Arguments &&...args)
noexcept(
false)
208 auto binder = *
this << sql;
209 (void)std::initializer_list<int>{
210 (binder << std::forward<Arguments>(args), 0)...};
212 binder << Mode::Blocking;
214 binder >> [&r](
const Result &result) { r = result; };
220#ifdef __cpp_impl_coroutine
221 template <
typename... Arguments>
222 internal::SqlAwaiter execSqlCoro(
const std::string &sql,
223 Arguments &&...args)
noexcept
225 auto binder = *
this << sql;
226 (void)std::initializer_list<int>{
227 (binder << std::forward<Arguments>(args), 0)...};
228 return internal::SqlAwaiter(std::move(binder));
241 template <
typename T>
242 internal::SqlAwaiter execSqlCoro(
const std::string &sql,
243 const std::vector<T> &args)
noexcept
245 auto binder = *
this << sql;
246 for (
const auto &arg : args)
250 return internal::SqlAwaiter(std::move(binder));
284 const std::function<
void(
bool)> &commitCallback =
285 std::function<
void(
bool)>(),
302 const std::function<
void(
const std::shared_ptr<Transaction> &)>
310 const std::function<
void(
const std::shared_ptr<Transaction> &)>
316#ifdef __cpp_impl_coroutine
317 orm::internal::TransactionAwaiter newTransactionCoro(
320 return orm::internal::TransactionAwaiter(
this, transType);
332 ClientType type()
const
337 const std::string &connectionInfo()
const
339 return connectionInfo_;
402 virtual void execSql(
406 std::vector<const char *> &¶meters,
407 std::vector<int> &&length,
408 std::vector<int> &&format,
409 ResultCallback &&rcb,
410 std::function<
void(
const std::exception_ptr &)> &&exceptCallback) = 0;
414 std::string connectionInfo_;
417using DbClientPtr = std::shared_ptr<DbClient>;
422 virtual void rollback() = 0;
424 virtual void setCommitCallback(
425 const std::function<
void(
bool)> &commitCallback) = 0;
432#ifdef __cpp_impl_coroutine
433inline void internal::TransactionAwaiter::await_suspend(
434 std::coroutine_handle<> handle)
436 assert(client_ !=
nullptr);
437 client_->newTransactionAsync(
438 [
this, handle](
const std::shared_ptr<Transaction> &transaction) {
439 if (transaction ==
nullptr)
440 setException(std::make_exception_ptr(TimeoutError(
441 "Timeout, no connection available for transaction")));
443 setValue(transaction);
TransactionType
Transaction locking mode.
Definition DbClient.h:48
@ Exclusive
Definition DbClient.h:51
@ Immediate
BEGIN IMMEDIATE — write lock acquired upfront (SQLite only).
Definition DbClient.h:50
@ Deferred
BEGIN — lock acquired on first write (default).
Definition DbClient.h:49
Database client abstract class.
Definition DbClient.h:105
virtual bool hasAvailableConnections() const noexcept=0
Check if there is a connection successfully established.
std::shared_ptr< Transaction > newTransaction(TransactionType transType) noexcept(false)
Convenience overload: create a transaction with a specific locking mode.
Definition DbClient.h:290
virtual void setTimeout(double timeout)=0
Set the Timeout value of execution of a SQL.
void execSqlAsync(const std::string &sql, FUNCTION1 &&rCallback, FUNCTION2 &&exceptCallback, Arguments &&...args) noexcept
Async and nonblocking method.
Definition DbClient.h:172
std::future< Result > execSqlAsyncFuture(const std::string &sql, Arguments &&...args) noexcept
Async and nonblocking method.
Definition DbClient.h:186
static std::shared_ptr< DbClient > newPgClient(const std::string &connInfo, size_t connNum, bool autoBatch=false)
Create a new database client with multiple connections;.
virtual void closeAll()=0
Close all connections in the client. usually used by Drogon in the quit() method.
virtual std::shared_ptr< Transaction > newTransaction(const std::function< void(bool)> &commitCallback=std::function< void(bool)>(), TransactionType transType=TransactionType::Deferred) noexcept(false)=0
Create a transaction object.
void newTransactionAsync(TransactionType transType, const std::function< void(const std::shared_ptr< Transaction > &)> &callback)
Definition DbClient.h:308
virtual void newTransactionAsync(const std::function< void(const std::shared_ptr< Transaction > &)> &callback, TransactionType transType=TransactionType::Deferred)=0
Create a transaction object in asynchronous mode.
internal::SqlBinder operator<<(const std::string &sql)
Mixin base class to identify drogon-db-specific exception types.
Definition Exception.h:51
Result set containing data returned by a query or command.
Definition Result.h:58
Definition DbClient.h:420
void closeAll() override
Close all connections in the client. usually used by Drogon in the quit() method.
Definition DbClient.h:427
Definition SqlBinder.h:293
Drogon Test is a minimal effort test framework developed because the major C++ test frameworks doesn'...
Definition Attribute.h:23
Definition coroutine.h:421