102 sqlgen::Result<sqlgen::Ref<sqlgen::Session<Connection>>>
acquire() noexcept {
105 auto session_result = pool_.acquire();
106 if (!session_result) {
107 return session_result;
114 bool needs_rebuild =
false;
115 std::string rollback_error;
117 auto rollback_result = (*session_result)->execute(
"ROLLBACK");
118 if (!rollback_result) {
119 needs_rebuild =
true;
120 rollback_error = rollback_result.error().what();
125 BOOST_LOG_SEV(lg(), warn)
126 <<
"Pool connection dead (ROLLBACK failed: "
127 << rollback_error <<
"). Rebuilding pool...";
130 session_result = pool_.acquire();
132 std::lock_guard lock(*reconnect_mutex_);
133 sqlgen::ConnectionPoolConfig cfg{
136 .wait_time_in_seconds = 1
138 auto new_pool = sqlgen::make_connection_pool<Connection>(
141 pool_ = std::move(*new_pool);
142 BOOST_LOG_SEV(lg(), info) <<
"Pool rebuilt successfully.";
144 BOOST_LOG_SEV(lg(), error)
145 <<
"Pool rebuild failed: " << new_pool.error().what();
146 return sqlgen::error(
"Pool rebuild failed: " +
147 std::string(new_pool.error().what()));
150 session_result = pool_.acquire();
151 if (!session_result)
return session_result;
152 (*session_result)->execute(
"ROLLBACK");
158 auto tz_result = (*session_result)->execute(
159 "SELECT set_config('TimeZone', 'UTC', false)");
161 return sqlgen::error(
"Failed to set session timezone to UTC: " +
162 std::string(tz_result.error().what()));
165 const auto tenant_id_str = tenant_id_.
to_string();
166 const std::string sql =
167 "SELECT set_config('app.current_tenant_id', '" +
168 tenant_id_str +
"', false)";
170 auto exec_result = (*session_result)->execute(sql);
172 return sqlgen::error(
"Failed to set tenant context: " +
173 std::string(exec_result.error().what()));
176 BOOST_LOG_SEV(lg(), debug) <<
"Set tenant context to: " << tenant_id_str;
179 if (party_id_.has_value()) {
180 const auto party_id_str = boost::uuids::to_string(*party_id_);
181 const std::string party_sql =
182 "SELECT set_config('app.current_party_id', '" +
183 party_id_str +
"', false)";
185 auto party_result = (*session_result)->execute(party_sql);
187 return sqlgen::error(
"Failed to set party context: " +
188 std::string(party_result.error().what()));
191 BOOST_LOG_SEV(lg(), debug) <<
"Set party context to: "
196 if (!visible_party_ids_.empty()) {
197 std::string ids_str =
"{";
198 for (std::size_t i = 0; i < visible_party_ids_.size(); ++i) {
199 if (i > 0) ids_str +=
",";
200 ids_str += boost::uuids::to_string(visible_party_ids_[i]);
204 const std::string vis_sql =
205 "SELECT set_config('app.visible_party_ids', '" +
206 ids_str +
"', false)";
208 auto vis_result = (*session_result)->execute(vis_sql);
210 return sqlgen::error(
"Failed to set visible party IDs: " +
211 std::string(vis_result.error().what()));
214 BOOST_LOG_SEV(lg(), debug) <<
"Set visible party IDs ("
215 << visible_party_ids_.size()
220 if (!actor_.empty()) {
221 const std::string actor_sql =
222 "SELECT set_config('app.current_actor', '" +
223 actor_ +
"', false)";
225 auto actor_result = (*session_result)->execute(actor_sql);
227 return sqlgen::error(
"Failed to set actor context: " +
228 std::string(actor_result.error().what()));
231 BOOST_LOG_SEV(lg(), debug) <<
"Set actor context to: " << actor_;
236 if (!service_account_.empty()) {
237 const std::string svc_sql =
238 "SELECT set_config('app.current_service', '" +
239 service_account_ +
"', false)";
240 auto svc_result = (*session_result)->execute(svc_sql);
242 return sqlgen::error(
"Failed to set service context: " +
243 std::string(svc_result.error().what()));
246 BOOST_LOG_SEV(lg(), debug) <<
"Set service context to: "
250 return session_result;