userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
query_queue.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/storages/postgres/query_queue.hpp
4
/// @brief An utility to execute multiple queries in a single network
5
/// round-trip.
6
7
#
include
<
userver
/
storages
/
postgres
/
options
.
hpp
>
8
#
include
<
userver
/
storages
/
postgres
/
query
.
hpp
>
9
#
include
<
userver
/
storages
/
postgres
/
result_set
.
hpp
>
10
11
#
include
<
userver
/
storages
/
postgres
/
detail
/
connection_ptr
.
hpp
>
12
#
include
<
userver
/
storages
/
postgres
/
detail
/
query_parameters
.
hpp
>
13
14
#
include
<
userver
/
utils
/
any_movable
.
hpp
>
15
#
include
<
userver
/
utils
/
fast_pimpl
.
hpp
>
16
17
USERVER_NAMESPACE_BEGIN
18
19
namespace
storages::
postgres
{
20
21
class
ParameterStore
;
22
23
/// @brief A container to enqueue queries in FIFO order and execute them all
24
/// within a single network round-trip.
25
///
26
/// Acquired from storages::postgres::Cluster, one is expected to `Push`
27
/// some queries into the queue and then `Collect` them into vector of results.
28
///
29
/// From a client point of view `Collect` is transactional: either all the
30
/// queries succeed or `Collect` rethrows the first error encountered. However,
31
/// this is *NOT* the case for the server: server treats all the provided
32
/// queries independently and is likely to execute subsequent queries even
33
/// after prior failures.
34
///
35
/// @warning If an explicit transaction ("BEGIN") or a modifying query is added
36
/// into the queue the behavior is unspecified. *Don't do that*.
37
///
38
/// @note Queries may or may not be sent to the server prior to `Collect` call.
39
///
40
/// @note Requires both pipelining and prepared statements to be enabled in the
41
/// driver, UINVARIANTS (that is, throws in release builds and aborts in debug
42
/// ones) that on construction.
43
class
QueryQueue
final
{
44
public
:
45
QueryQueue(
CommandControl
default_cc, detail::ConnectionPtr&& conn);
46
47
QueryQueue(QueryQueue&&)
noexcept
;
48
QueryQueue& operator=(QueryQueue&&)
noexcept
;
49
50
QueryQueue(
const
QueryQueue&) =
delete
;
51
QueryQueue& operator=(
const
QueryQueue&) =
delete
;
52
53
~QueryQueue();
54
55
/// Reserve internal storage to hold this amount of queries.
56
void
Reserve
(std::size_t size);
57
58
/// Add a query into the queue with specified command-control.
59
/// CommandControl is used as following: 'execute' is used as a timeout for
60
/// preparing the statement (if needed), 'statement' is used as a statement
61
/// timeout for later execution.
62
template
<
typename
... Args>
63
void
Push
(
CommandControl
cc,
const
Query& query,
const
Args&... args);
64
void
Push(
CommandControl
cc,
const
Query& query,
const
ParameterStore
& store);
65
66
/// Add a query into the queue with default command-control.
67
template
<
typename
... Args>
68
void
Push
(
const
Query& query,
const
Args&... args);
69
void
Push(
const
Query& query,
const
ParameterStore
& store);
70
71
/// Collect results of all the queued queries, with specified timeout.
72
/// Either returns a vector of N `ResultSet`s, where N is the number of
73
/// queries enqueued, or rethrow the first error encountered, be that a query
74
/// execution error or a timeout.
75
[[nodiscard]] std::vector<
ResultSet
>
Collect
(TimeoutDuration timeout);
76
77
/// Collect results of all the queued queries, with default timeout.
78
/// Either returns a vector of N `ResultSet`s, where N is the number of
79
/// queries enqueued, or rethrow the first error encountered, be that a query
80
/// execution error or a timeout.
81
[[nodiscard]] std::vector<
ResultSet
>
Collect
();
82
83
private
:
84
struct
ParamsHolder
final
{
85
// We only need to know what's here at construction (and at construction we
86
// do know), after that we just need to preserve lifetime.
87
USERVER_NAMESPACE::
utils
::AnyMovable any_params
{
}
;
88
// This here knows what's there actually is in params.
89
detail::QueryParameters params_proxy;
90
};
91
92
const
UserTypes
& GetConnectionUserTypes()
const
;
93
94
void
DoPush(
CommandControl
cc,
const
Query& query, ParamsHolder&& params);
95
96
void
ValidateUsage()
const
;
97
98
CommandControl
default_cc_;
99
detail::ConnectionPtr conn_;
100
101
struct
QueriesStorage;
102
USERVER_NAMESPACE::
utils
::FastPimpl<QueriesStorage, 56, 8> queries_storage_;
103
};
104
105
template
<
typename
... Args>
106
void
QueryQueue::
Push
(
CommandControl
cc,
const
Query& query,
const
Args&... args) {
107
ParamsHolder holder{};
108
auto
& params = holder.any_params.Emplace<detail::StaticQueryParameters<
sizeof
...(args)>>();
109
params.Write(GetConnectionUserTypes(), args...);
110
holder.params_proxy = detail::QueryParameters{params};
111
DoPush(cc, query, std::move(holder));
112
}
113
114
template
<
typename
... Args>
115
void
QueryQueue::
Push
(
const
Query& query,
const
Args&... args) {
116
Push(default_cc_, query, args...);
117
}
118
119
}
// namespace storages::postgres
120
121
USERVER_NAMESPACE_END
userver
storages
postgres
query_queue.hpp
Generated on
for userver by
Doxygen
1.17.0