@@ -81,27 +81,47 @@ bool Connection::throwQueryError(game_state& gs, mariadb::connection_ref connect
8181GameDataDBAsyncResult* Connection::pushAsyncQuery (game_state& gs, mariadb::connection_ref connection, auto_array<game_value> boundValues, r_string queryString) {
8282 auto gd_res = new GameDataDBAsyncResult ();
8383 gd_res->data = std::make_shared<GameDataDBAsyncResult::dataT>();
84+
85+
86+ // If we give them to task, it will destruct the array after task is done, and may call dealloc int he pool allocator
87+ std::vector<
88+ std::variant<float , bool , r_string>
89+ > boundValuesQuery;
90+
91+ for (auto & it : boundValues) {
92+ switch (it.type_enum ()) {
93+ case game_data_type::SCALAR: boundValuesQuery.emplace_back (static_cast <float >(it)); break ;
94+ case game_data_type::BOOL: boundValuesQuery.emplace_back (static_cast <bool >(it)); break ;
95+ case game_data_type::STRING: boundValuesQuery.emplace_back (static_cast <r_string>(it)); break ;
96+ default :;
97+ }
98+ }
99+
84100 gd_res->data ->fut = Threading::get ().pushTask (connection,
85- [queryString, boundValues , result = gd_res->data , &gs](mariadb::connection_ref con) -> bool {
101+ [queryString, boundValuesQuery , result = gd_res->data , &gs](mariadb::connection_ref con) -> bool {
86102 try {
87103 auto statement = con->create_statement (queryString);
88104
89- if (statement->get_bind_count () != boundValues .size ()) {
105+ if (statement->get_bind_count () != boundValuesQuery .size ()) {
90106 invoker_lock l;
91107 throwQueryError (gs, con, 2 ,
92- r_string (" Invalid number of bind values. Expected " sv)+std::to_string (statement->get_bind_count ())+" got " sv+std::to_string (boundValues .size ())
108+ r_string (" Invalid number of bind values. Expected " sv)+std::to_string (statement->get_bind_count ())+" got " sv+std::to_string (boundValuesQuery .size ())
93109 , queryString);
94110 return false ;
95111 }
96112 uint32_t idx = 0 ;
97- for (auto & it : boundValues) {
98-
99- switch (it.type_enum ()) {
100- case game_data_type::SCALAR: statement->set_float (idx++, static_cast <float >(it)); break ;
101- case game_data_type::BOOL: statement->set_boolean (idx++, static_cast <bool >(it)); break ;
102- case game_data_type::STRING: statement->set_string (idx++, static_cast <r_string>(it)); break ;
103- default :;
104- }
113+ for (auto & it : boundValuesQuery) {
114+ std::visit ([&idx, &statement](auto && arg) {
115+ using T = std::decay_t <decltype (arg)>;
116+ if constexpr (std::is_same_v<T, float >)
117+ statement->set_float (idx++, arg);
118+ else if constexpr (std::is_same_v<T, bool >)
119+ statement->set_boolean (idx++, arg);
120+ else if constexpr (std::is_same_v<T, r_string>)
121+ statement->set_string (idx++, arg);
122+ else
123+ static_assert (false , " non-exhaustive visitor!" );
124+ }, it);
105125 }
106126 result->res = statement->query ();
107127 return true ;
@@ -229,7 +249,6 @@ game_value Connection::cmd_execute(game_state& gs, game_value_parameter con, gam
229249
230250 uint32_t idx = 0 ;
231251 for (auto & it : query->boundValues ) {
232-
233252 switch (it.type_enum ()) {
234253 case game_data_type::SCALAR: statement->set_float (idx++, static_cast <float >(it)); break ;
235254 case game_data_type::BOOL: statement->set_boolean (idx++, static_cast <bool >(it)); break ;
@@ -274,7 +293,6 @@ game_value Connection::cmd_executeAsync(game_state& gs, game_value_parameter con
274293 auto session = con.get_as <GameDataDBConnection>()->session ;
275294 auto query = qu.get_as <GameDataDBQuery>();
276295
277-
278296 auto gd_res = pushAsyncQuery (gs, session, query->boundValues , query->getQueryString ());
279297 Threading::get ().pushAsyncWork (gd_res);
280298 __itt_task_end (domainConnection);
0 commit comments