userver: /data/code/userver/odbc/include/userver/storages/odbc/cluster.hpp Source File
Loading...
Searching...
No Matches
cluster.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/odbc/cluster.hpp
4/// @brief @copybrief storages::odbc::Cluster
5
6#include <chrono>
7#include <optional>
8
9#include <userver/clients/dns/resolver_fwd.hpp>
10#include <userver/engine/task/task_processor_fwd.hpp>
11#include <userver/utils/statistics/writer.hpp>
12
13#include <userver/storages/odbc/bulk.hpp>
14#include <userver/storages/odbc/cluster_types.hpp>
15#include <userver/storages/odbc/command_control.hpp>
16#include <userver/storages/odbc/cursor.hpp>
17#include <userver/storages/odbc/impl/parameter.hpp>
18#include <userver/storages/odbc/parameter_store.hpp>
19#include <userver/storages/odbc/query.hpp>
20#include <userver/storages/odbc/result_set.hpp>
21#include <userver/storages/odbc/settings.hpp>
22#include <userver/storages/odbc/transaction.hpp>
23
24USERVER_NAMESPACE_BEGIN
25
26namespace storages::odbc {
27
28namespace detail {
29
30class ClusterImpl;
31struct BulkLayout;
32using ClusterImplPtr = std::unique_ptr<ClusterImpl>;
33
34} // namespace detail
35
36/// @brief ODBC cluster client: queries and transactions against pooled DSNs
37class Cluster {
38public:
39 Cluster(const settings::ODBCClusterSettings& settings, clients::dns::Resolver* resolver);
40 Cluster(
41 const settings::ODBCClusterSettings& settings,
42 clients::dns::Resolver* resolver,
43 engine::TaskProcessor& blocking_task_processor
44 );
45
46 ~Cluster();
47
48 /// @brief Execute a statement, binding every argument to an ODBC `?` placeholder.
49 ///
50 /// @warning Never interpolate untrusted values into @p query. Passing them as
51 /// separate arguments ensures that they are sent to the ODBC driver as data.
52 template <typename... Args>
53 requires((impl::kIsParameterArgument<Args> && ...))
54 ResultSet Execute(ClusterHostTypeFlags flags, const Query& query, const Args&... args) {
55 return Execute(flags, std::nullopt, query, args...);
56 }
57
58 /// @brief Execute a statement with per-operation timeout overrides.
59 template <typename... Args>
60 requires((impl::kIsParameterArgument<Args> && ...))
61 ResultSet Execute(
62 ClusterHostTypeFlags flags,
63 OptionalCommandControl command_control,
64 const Query& query,
65 const Args&... args
66 ) {
67 return DoExecute(command_control, flags, query, impl::MakeParameterList(args...));
68 }
69
70 /// @brief Execute a statement with an owning dynamic parameter list.
71 ResultSet Execute(ClusterHostTypeFlags flags, const Query& query, const ParameterStore& store);
72
73 /// @brief Execute a statement with a dynamic parameter list and timeout overrides.
74 ResultSet Execute(
75 ClusterHostTypeFlags flags,
76 OptionalCommandControl command_control,
77 const Query& query,
78 const ParameterStore& store
79 );
80
81 /// @brief Execute a row-producing statement as an incremental cursor.
82 ///
83 /// @warning The cursor pins a pooled connection until it becomes terminal.
84 template <typename... Args>
85 requires((impl::kIsParameterArgument<Args> && ...))
86 Cursor ExecuteCursor(ClusterHostTypeFlags flags, const Query& query, const Args&... args) {
87 return ExecuteCursor(flags, std::nullopt, query, args...);
88 }
89
90 /// @brief Execute an incremental cursor with per-operation timeout
91 /// overrides. The resolved durations are reused as a fresh budget for every
92 /// Fetch call.
93 template <typename... Args>
94 requires((impl::kIsParameterArgument<Args> && ...))
96 ClusterHostTypeFlags flags,
97 OptionalCommandControl command_control,
98 const Query& query,
99 const Args&... args
100 ) {
101 return DoExecuteCursor(command_control, flags, query, impl::MakeParameterList(args...));
102 }
103
104 Cursor ExecuteCursor(ClusterHostTypeFlags flags, const Query& query, const ParameterStore& store);
105
106 Cursor ExecuteCursor(
107 ClusterHostTypeFlags flags,
108 OptionalCommandControl command_control,
109 const Query& query,
110 const ParameterStore& store
111 );
112
113 /// Execute rows as bounded chunks of DML that must not return result sets.
114 /// Earlier chunks may remain committed if a later row fails; no executed
115 /// chunk is retried. Use a Transaction when rollback atomicity is needed.
116 BulkResult ExecuteBulk(
117 ClusterHostTypeFlags flags,
118 const Query& query,
119 const BulkParameterStore& rows,
120 std::size_t chunk_rows = kDefaultBulkRows
121 );
122
123 /// Execute bulk DML with per-operation timeout overrides.
124 BulkResult ExecuteBulk(
125 ClusterHostTypeFlags flags,
126 OptionalCommandControl command_control,
127 const Query& query,
128 const BulkParameterStore& rows,
129 std::size_t chunk_rows = kDefaultBulkRows
130 );
131
132 Transaction Begin(ClusterHostTypeFlags flags);
133
134 Transaction Begin(ClusterHostTypeFlags flags, OptionalCommandControl command_control);
135
136 /// Start a transaction with explicit ODBC isolation/access options.
137 Transaction Begin(ClusterHostTypeFlags flags, const TransactionOptions& options);
138
139 /// Start a transaction with explicit options and timeout overrides.
140 Transaction Begin(
141 ClusterHostTypeFlags flags,
142 const TransactionOptions& options,
143 OptionalCommandControl command_control
144 );
145
146 void WriteStatistics(utils::statistics::Writer& writer) const;
147
148 /// @brief Set default command control (timeouts) from dynamic config
149 void SetDefaultCommandControl(const CommandControl& cc);
150
151 /// @brief Atomically replace command controls looked up by the current
152 /// task-inherited HTTP handler path and method.
153 ///
154 /// Each configured field overlays the lower-priority default independently.
155 /// Passing an empty map clears the complete handler layer.
157
158 /// @brief Atomically replace command controls looked up by Query name.
159 ///
160 /// Each configured field overlays default and handler fields independently.
161 /// Unnamed queries skip this layer. Passing an empty map clears it.
163
164 /// @brief Set the per-pool bound for named query latency and error metrics.
165 ///
166 /// A zero bound disables accounting and clears all retained named query
167 /// names. Shrinking the bound evicts the least recently used names. Each
168 /// retained name exports three metric series.
169 void SetStatementMetricsSettings(const settings::StatementMetricsSettings& settings);
170
171 /// @brief Set the per-connection prepared statement cache bound.
172 ///
173 /// A zero bound disables and clears the cache. Shrinking evicts the least
174 /// recently used statements; growing preserves existing entries. Existing
175 /// physical connections apply changes before their next operation.
176 void SetPreparedStatementCacheSettings(const settings::PreparedStatementCacheSettings& settings);
177
178 /// @brief Atomically replace cluster pools for future operations.
179 /// Existing queries and transactions keep their old pools alive.
180 void UpdateSettings(const settings::ODBCClusterSettings& settings);
181
182 /// @cond
183 void UpdateDsns(const std::vector<std::string>& dsns);
184 void SetPoolSettingsOverride(std::optional<settings::PoolSettings> settings);
185 void SetPreparedStatementCacheSettingsOverride(std::optional<settings::PreparedStatementCacheSettings> settings);
186 void ApplyDynamicCommandControls(
187 CommandControl default_command_control,
188 CommandControlByHandlerMap handlers_command_control,
189 CommandControlByQueryMap queries_command_control
190 );
191 /// @endcond
192
193 /// @brief Get current default network timeout
194 std::optional<std::chrono::milliseconds> GetDefaultNetworkTimeout() const;
195
196 /// @brief Get current default statement timeout
197 std::optional<std::chrono::milliseconds> GetDefaultStatementTimeout() const;
198
199private:
200 ResultSet DoExecute(
201 OptionalCommandControl command_control,
202 ClusterHostTypeFlags flags,
203 const Query& query,
204 const impl::ParameterList& parameters
205 );
206 Cursor DoExecuteCursor(
207 OptionalCommandControl command_control,
208 ClusterHostTypeFlags flags,
209 const Query& query,
210 const impl::ParameterList& parameters
211 );
212 BulkResult DoExecuteBulk(
213 OptionalCommandControl command_control,
214 ClusterHostTypeFlags flags,
215 const Query& query,
216 const impl::ParameterRows& rows,
217 const detail::BulkLayout& layout,
218 std::size_t chunk_rows
219 );
220
221 detail::ClusterImplPtr impl_;
222};
223
224} // namespace storages::odbc
225
226USERVER_NAMESPACE_END