OZO 「お象」
Boost.Asio and libpq based asynchronous PostgreSQL unofficial header-only C++17 client library.

Description

Database requests related functions.

Functions

template<typename Connection , typename Executor = boost::asio::system_executor>
cancel_handle< Executor > ozo::get_cancel_handle (const Connection &connection, Executor &&executor=Executor{})
 Get cancel handle for the cancel operation. More...
 
template<typename Executor , typename TimeConstraint , typename CancelCompletionToken >
auto ozo::cancel (cancel_handle< Executor > &&handle, io_context &io, TimeConstraint time_constraint, CancelCompletionToken &&token)
 Cancel execution of current request on a database backend. More...
 
template<typename Executor , typename CancelCompletionToken >
auto ozo::cancel (cancel_handle< Executor > &&handle, CancelCompletionToken &&token)
 Cancel execution of current request on a database backend. More...
 
template<typename ConnectionProvider , typename BinaryQueryConvertible , typename TimeConstraint , typename CompletionToken >
decltype(auto) ozo::execute (ConnectionProvider &&provider, BinaryQueryConvertible &&query, TimeConstraint time_constraint, CompletionToken &&token)
 Executes query with no result data expected. More...
 
template<typename ConnectionProvider , typename BinaryQueryConvertible , typename CompletionToken >
decltype(auto) ozo::execute (ConnectionProvider &&provider, BinaryQueryConvertible &&query, CompletionToken &&token)
 Executes query with no result data expected. More...
 
template<typename ConnectionProvider , typename BinaryQueryConvertible , typename TimeConstraint , typename Out , typename CompletionToken >
decltype(auto) ozo::request (ConnectionProvider &&provider, BinaryQueryConvertible &&query, TimeConstraint time_constraint, Out out, CompletionToken &&token)
 Executes query and retrives a result from a database with time constraint. More...
 
template<typename ConnectionProvider , typename BinaryQueryConvertible , typename Out , typename CompletionToken >
decltype(auto) ozo::request (ConnectionProvider &&provider, BinaryQueryConvertible &&query, Out out, CompletionToken &&token)
 Executes query and retrives a result from a database. More...
 
template<typename T >
constexpr auto ozo::into (T &v)
 Shortcut for create result container back inserter. More...
 
template<typename T >
constexpr auto ozo::into (basic_result< T > &v) noexcept
 Shortcut for create reference wrapper for ozo::basic_result. More...
 

Function Documentation

◆ cancel() [1/2]

template<typename Executor , typename CancelCompletionToken >
auto ozo::cancel ( cancel_handle< Executor > &&  handle,
CancelCompletionToken &&  token 
)

Cancel execution of current request on a database backend.

This version executes cancel operation without a time constraint.

Note
The function does not particitate in ADL since could be implemented via functional object.
Parameters
handle— handle for the cancel operation, should be obtained via ozo::get_cancel_handle.
token— valid CancelCompletionToken (see time constraint version of ozo::cancel() for details).
Returns
deduced from CancelCompletionToken.
Warning
Use it carefully because you can't cancel this cancel() operation. The only option is to stop wait.

◆ cancel() [2/2]

template<typename Executor , typename TimeConstraint , typename CancelCompletionToken >
auto ozo::cancel ( cancel_handle< Executor > &&  handle,
io_context &  io,
TimeConstraint  time_constraint,
CancelCompletionToken &&  token 
)

Cancel execution of current request on a database backend.

Sometimes you need to cancel request to a database due to operation time constraint. In case of closing connection, PostgreSQL backend will continue to execute request anyway. So to prevent such waste of database resources it is best practice to cancel the execution of the request by sending special command.

Note
The function does not particitate in ADL since could be implemented via functional object.
If a timer hits the specified time constraint only waiting process would be canceled. The cancel operation itself would continue to execute since there is no way to cancel it. User should take it into account planning to use specified executor.
It is not recommended to use cancel() with external connection poolers like pgbouncer or Odyssey out of explicit transaction (with autocommit feature), since it could lead to a canceling of concurrent query, which shares the same backend.
Parameters
handle— handle for the cancel operation, should be obtained via ozo::get_cancel_handle.
io— io_context on which the operation timer will run.
time_constraint— time constraint to wait for the operation complete.
token— valid CancelCompletionToken which is described below.
Returns
deduced from CancelCompletionToken.

CancelCompletionToken

It determines how to continue with an asynchronous cancel operation result when the operation is complete.

Valid CancelCompletionToken is one of:

  • Callback with signature void(ozo::error_code ec, std::string error_message). In this case ozo::cancel() returns void. First argument provides error code, second - error message from the undelying libpq library.
  • boost::asio::use_future — to get a future on the asynchronous operation result. In this case ozo::cancel() will return std::future<void>. Additional error message from the undelying libpq library will be lost. For this reason the completion token is not recommended for use in production code. In case of synchronization is needed it is better to use a callback with promise and future are used directely.
  • boost::asio::yield_context — to use async operation with Boost.Coroutine. Asynchronous function in this case will return std::string.
    Note
    To get error message from the undelying libpq library error code binding should be used to avoid exception in case of error.
  • any other type supported by boost::asio::async_result.

Example

ozo::io_context io;
boost::asio::steady_timer timer(io);
boost::asio::spawn(io, [&io, &timer](auto yield){
const ozo::connection_info conn_info(OZO_PG_TEST_CONNINFO);
auto conn = ozo::get_connection(conn_info[io], yield[ec]);
assert(!ec);
// We want to cancel query if it takes too long
boost::asio::spawn(yield, [&io, &timer, handle = get_cancel_handle(conn)](auto yield) mutable {
// Wait a second for the request result
timer.expires_after(1s);
timer.async_wait(yield);
// In this case guard is needed since cancel will be served with
// external system executor and we need to protect our io_context
// from stop until cancel continuation will be called. It is not
// necessary if you already protect the io service with a work guard.
auto guard = boost::asio::make_work_guard(io);
// Cancel should be performed within 5 seconds, othervise the
// coroutine will be released.
auto error_msg = ozo::cancel(std::move(handle), io, 5s, yield[ec]);
if (ec) {
std::cerr << ec.message() << ", " << error_msg << std::endl;
}
});
ozo::execute(conn, "SELECT pg_sleep(1000000)"_SQL, yield[ec]);
assert(ec == ozo::sqlstate::query_canceled);
});
io.run();

◆ execute() [1/2]

template<typename ConnectionProvider , typename BinaryQueryConvertible , typename CompletionToken >
decltype(auto) ozo::execute ( ConnectionProvider &&  provider,
BinaryQueryConvertible &&  query,
CompletionToken &&  token 
)

Executes query with no result data expected.

This function is time constrain free shortcut to ozo::execute() function. Its call is equal to ozo::execute(provider, query, ozo::none, token) call.

Note
The function does not particitate in ADL since could be implemented via functional object.
Parameters
provider— connection provider object
query— query object to execute
token— operation CompletionToken.
Returns
deduced from CompletionToken.

References ozo::get_operation_initiator(), and ozo::none.

◆ execute() [2/2]

template<typename ConnectionProvider , typename BinaryQueryConvertible , typename TimeConstraint , typename CompletionToken >
decltype(auto) ozo::execute ( ConnectionProvider &&  provider,
BinaryQueryConvertible &&  query,
TimeConstraint  time_constraint,
CompletionToken &&  token 
)

Executes query with no result data expected.

This function is same as ozo::request() function except it does not provide any result data. It suitable to use with UPDATE INSERT statements, or invoking procedures without result.

Note
The function does not particitate in ADL since could be implemented via functional object.
Parameters
provider— connection provider object
query— query object to execute
time_constraint— request #TimeConstraint; this time constrain includes time for getting connection from provider.
token— operation CompletionToken.
Returns
deduced from CompletionToken.

◆ get_cancel_handle()

template<typename Connection , typename Executor = boost::asio::system_executor>
cancel_handle< Executor > ozo::get_cancel_handle ( const Connection connection,
Executor &&  executor = Executor{} 
)

Get cancel handle for the cancel operation.

Parameters
connectionConnection with active operation to cancel.
executor— Executor on which the operation will be executed. Default executor is boost::asio::system_executor.
Returns
null-state object if given connection is in bad state.
initialized object if given connection is in good state.

Since libpq's cancel operation implementation is synchronous only it would block a thread where executed. That's why it needs a dedicated Executor. User should specify an executor to implement a proper execution strategy, e.g. the operations' queue which would be handled in a dedicated thread and so on.

References ozo::get_native_handle().

◆ into() [1/2]

template<typename T >
constexpr auto ozo::into ( basic_result< T > &  v)
constexprnoexcept

Shortcut for create reference wrapper for ozo::basic_result.

This shortcut creates reference wrapper for ozo::basic_result to obtain raw result into it.

Example

// Query statement
const auto query = "SELECT id, name FROM users_info WHERE amount>="_SQL + std::int64_t(25);
ozo::request(conn_info[io], query, ozo::into(res), boost::asio::use_future);
Parameters
vozo::basic_result object for rows.

◆ into() [2/2]

template<typename T >
constexpr auto ozo::into ( T &  v)
constexpr

Shortcut for create result container back inserter.

This shortcut defines insert iterator for row container.

Example

// Query statement
const auto query = "SELECT id, name FROM users_info WHERE amount>="_SQL + std::int64_t(25);
ozo::request(conn_info[io], query, ozo::into(rows), boost::asio::use_future);
Parameters
v— container for rows

◆ request() [1/2]

template<typename ConnectionProvider , typename BinaryQueryConvertible , typename Out , typename CompletionToken >
decltype(auto) ozo::request ( ConnectionProvider &&  provider,
BinaryQueryConvertible &&  query,
Out  out,
CompletionToken &&  token 
)

Executes query and retrives a result from a database.

This function is time constrain free shortcut to ozo::request() function. Its call is equal to ozo::request(provider, query, ozo::none, out, token) call.

Note
The function does not participate in ADL since could be implemented via functional object.
Parameters
provider— connection provider to get connection from.
query— query object to request from a database.
out— output object like Iterator, InsertIterator or ozo::result.
token— operation CompletionToken.
Returns
deduced from CompletionToken.

References ozo::get_operation_initiator(), and ozo::none.

◆ request() [2/2]

template<typename ConnectionProvider , typename BinaryQueryConvertible , typename TimeConstraint , typename Out , typename CompletionToken >
decltype(auto) ozo::request ( ConnectionProvider &&  provider,
BinaryQueryConvertible &&  query,
TimeConstraint  time_constraint,
Out  out,
CompletionToken &&  token 
)

Executes query and retrives a result from a database with time constraint.

The function sends request to a database and provides result via out parameter. The function can be called as any of Boost.Asio asynchronous function with CompletionToken. The request would be cancelled if time constrain is reached while performing.

Note
The function does not participate in ADL since could be implemented via functional object.
Parameters
provider— connection provider object to get connection from.
query— query object to request from a database.
time_constraint— request #TimeConstraint; this time constrain includes time for getting connection from provider.
out— output object like Iterator, InsertIterator or ozo::result.
token— operation CompletionToken.
Returns
deduced from CompletionToken.

Example

#include <ozo/request.h>
#include <ozo/connection_info.h>
#include <ozo/shortcuts.h>
#include <boost/asio.hpp>
int main() {
boost::asio::io_context io;
auto conn_info = ozo::connection_info("host=... port=...");
using namespace ozo::literals;
using namespace std::chrono_literals;
const auto query = "SELECT id, name FROM users_info WHERE amount>="_SQL + std::int64_t(25);
ozo::request(conn_info[io], query, 500ms, ozo::into(rows),
[&](ozo::error_code ec, auto conn) {
if (ec) {
std::cerr << ec.message() << " | " << error_message(conn);
if (!is_null_recursive(conn)) {
std::cerr << " | " << get_error_context(conn);
}
return;
};
assert(ozo::connection_good(conn));
std::cout << "id" << '\t' << "name" << std::endl;
for(auto& row: res) {
std::cout << std::get<0>(row) << '\t'
<< std::get<1>(row) << std::endl;
}
});
io.run();
}
ozo::request
decltype(auto) request(ConnectionProvider &&provider, BinaryQueryConvertible &&query, TimeConstraint time_constraint, Out out, CompletionToken &&token)
Executes query and retrives a result from a database with time constraint.
ozo::error_code
boost::system::error_code error_code
Error code representation of the library.
Definition: error.h:38
ozo::error_message
std::string_view error_message(const Connection &conn)
Get native libpq error message.
Definition: connection.h:97
ozo::rows_of
std::vector< typed_row< Ts... > > rows_of
Shortcut for easy result container definition.
Definition: shortcuts.h:37
ozo::into
constexpr auto into(T &v)
Shortcut for create result container back inserter.
Definition: shortcuts.h:85
ozo::execute
decltype(auto) execute(ConnectionProvider &&provider, BinaryQueryConvertible &&query, TimeConstraint time_constraint, CompletionToken &&token)
Executes query with no result data expected.
ozo::is_null_recursive
constexpr bool is_null_recursive(T &&v) noexcept
Indicates if one of unwrapped values is in null state.
Definition: recursive.h:78
ozo::connection_info
Connection source to a single host.
Definition: connection_info.h:28
ozo::get_connection
decltype(auto) get_connection(T &&provider, TimeConstraint time_constraint, CompletionToken &&token)
Get a connection object from connection provider with time constaint.
ozo::get_cancel_handle
cancel_handle< Executor > get_cancel_handle(const Connection &connection, Executor &&executor=Executor{})
Get cancel handle for the cancel operation.
Definition: cancel.h:157
ozo::cancel
auto cancel(cancel_handle< Executor > &&handle, io_context &io, TimeConstraint time_constraint, CancelCompletionToken &&token)
Cancel execution of current request on a database backend.
ozo::connection_good
bool connection_good(const Connection &conn) noexcept
Indicates if connection state is not bad.
Definition: connection.h:391
ozo::basic_result
Database raw result representation.
Definition: result.h:263
ozo::get_error_context
const auto & get_error_context(const Connection &conn)
Get additional error context.
Definition: connection.h:124