driver-sqlpool.c revision 191eb75dd8c688dc1669492b842233decaf9cacc
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2010-2015 Dovecot authors, see the included COPYING file */
d35fee8d1e5e31614dba5e64d45ed23c7d6bfa53Timo Sirainen /* all connections from all hosts */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ARRAY(struct sqlpool_connection) all_connections;
6bc0f424bcdb9119d8159874cf98adfa53eefd9aTimo Sirainen /* index of last connection in all_connections that was used to
ad850190d946d34966a56838cfdb216e021b5b5fTimo Sirainen send a query. */
d35fee8d1e5e31614dba5e64d45ed23c7d6bfa53Timo Sirainen /* queued requests */
d35fee8d1e5e31614dba5e64d45ed23c7d6bfa53Timo Sirainen struct sqlpool_request *requests_head, *requests_tail;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* requests are a) queries */
846624bdec0d5deec6cf22071158221391ec5f2dAki Tuomi /* b) transaction waiters */
846624bdec0d5deec6cf22071158221391ec5f2dAki Tuomisqlpool_add_connection(struct sqlpool_db *db, struct sqlpool_host *host,
846624bdec0d5deec6cf22071158221391ec5f2dAki Tuomi unsigned int host_idx);
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainendriver_sqlpool_query_callback(struct sql_result *result,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainendriver_sqlpool_commit_callback(const char *error,
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainensqlpool_request_new(struct sqlpool_db *db, const char *query)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainensqlpool_request_free(struct sqlpool_request **_request)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(request->prev == NULL && request->next == NULL);
abe7afb8f1766fbcef1b9df513109e43d7d16e49Timo Sirainensqlpool_request_abort(struct sqlpool_request **_request)
ab70f55bb8d824ca1ed7c74196f2f502edd29cc7Timo Sirainen request->callback(&sql_not_connected_result, request->context);
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainendriver_sqlpool_new_conn_trans(struct sqlpool_transaction_context *trans,
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainen /* backend will use our queries list (we might still append more
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainen queries to the list) */
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainen for (query = conn_trans->head; query != NULL; query = query->next)
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainensqlpool_request_handle_transaction(struct sql_db *conndb,
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainen conn_trans = driver_sqlpool_new_conn_trans(trans, conndb);
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainensqlpool_request_send_next(struct sqlpool_db *db, struct sql_db *conndb)
69e03a846f6980144aa75bff0590c04852bffbbcTimo Sirainen if (db->requests_head == NULL || !SQL_DB_IS_READY(conndb))
69e03a846f6980144aa75bff0590c04852bffbbcTimo Sirainen DLLIST2_REMOVE(&db->requests_head, &db->requests_tail, request);
69e03a846f6980144aa75bff0590c04852bffbbcTimo Sirainen sqlpool_request_handle_transaction(conndb, request->trans);
69e03a846f6980144aa75bff0590c04852bffbbcTimo Sirainenstatic void sqlpool_reconnect(struct sql_db *conndb)
69e03a846f6980144aa75bff0590c04852bffbbcTimo Sirainensqlpool_find_host_with_least_connections(struct sqlpool_db *db,
69e03a846f6980144aa75bff0590c04852bffbbcTimo Sirainen unsigned int *host_idx_r)
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen unsigned int i, count;
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen hosts = array_get_modifiable(&db->hosts, &count);
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen if (min->connection_count > hosts[i].connection_count) {
69e03a846f6980144aa75bff0590c04852bffbbcTimo Sirainenstatic bool sqlpool_have_successful_connections(struct sqlpool_db *db)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainensqlpool_handle_connect_failed(struct sqlpool_db *db, struct sql_db *conndb)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen /* increase delay between reconnections to this
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen if (conndb->connect_delay > SQL_CONNECT_MAX_DELAY)
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen conndb->connect_delay = SQL_CONNECT_MAX_DELAY;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen /* reconnect after the delay */
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen conndb->to_reconnect = timeout_add(conndb->connect_delay * 1000,
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainen /* if we have zero successful hosts and there still are hosts
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainen without connections, connect to one of them. */
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainen if (!sqlpool_have_successful_connections(db)) {
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainen host = sqlpool_find_host_with_least_connections(db, &host_idx);
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainen (void)sqlpool_add_connection(db, host, host_idx);
620b5ed41650da63b0ba15c489f9f312231d5d9bTimo Sirainensqlpool_state_changed(struct sql_db *conndb, enum sql_db_state prev_state,
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainen conndb->connect_delay = SQL_CONNECT_MIN_DELAY;
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainensqlpool_add_connection(struct sqlpool_db *db, struct sqlpool_host *host,
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainen conndb = db->driver->v.init(host->connect_string);
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainen conndb->state_change_callback = sqlpool_state_changed;
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainen conndb->connect_delay = SQL_CONNECT_MIN_DELAY;
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainen conn = array_append_space(&db->all_connections);
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainensqlpool_add_new_connection(struct sqlpool_db *db)
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainen host = sqlpool_find_host_with_least_connections(db, &host_idx);
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainen if (host->connection_count >= db->connection_limit)
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainen return sqlpool_add_connection(db, host, host_idx);
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainenstatic const struct sqlpool_connection *
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainensqlpool_find_available_connection(struct sqlpool_db *db,
8ac66221e8fdc2c5523cff1893e0d1c5de25fa49Timo Sirainen unsigned int i, count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen conns = array_get(&db->all_connections, &count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; i < count; i++) {
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen unsigned int idx = (i + db->last_query_conn_idx + 1) % count;
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainen if (!SQL_DB_IS_READY(conndb) && conndb->to_reconnect == NULL) {
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainen /* see if we could reconnect to it immediately */
c4877db8b6559846f4b58be8e42422dc734c193fTimo Sirainen if (conndb->state != SQL_DB_STATE_DISCONNECTED)
8b9342aa96b2f297e23afb261f9f7dd859800952Timo Sirainendriver_sqlpool_get_connection(struct sqlpool_db *db,
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen const struct sqlpool_connection *conn, *conns;
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen unsigned int i, count;
f81801789c71f64a2fc3c44d09f9864bbc68cd45Timo Sirainen conn = sqlpool_find_available_connection(db, unwanted_host_idx,
f81801789c71f64a2fc3c44d09f9864bbc68cd45Timo Sirainen if (conn == NULL && unwanted_host_idx != UINT_MAX) {
f81801789c71f64a2fc3c44d09f9864bbc68cd45Timo Sirainen /* maybe there are no wanted hosts. use any of them. */
f81801789c71f64a2fc3c44d09f9864bbc68cd45Timo Sirainen conn = sqlpool_find_available_connection(db, UINT_MAX,
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen /* no connected connections. connect_delays may have gotten too
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen high, reset all of them to see if some are still alive. */
9af06b76539445d2d84d6e1bcb91685b6abeb4e0Timo Sirainen conns = array_get(&db->all_connections, &count);
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen for (i = 0; i < count; i++) {
f81801789c71f64a2fc3c44d09f9864bbc68cd45Timo Sirainen if (conndb->connect_delay > SQL_CONNECT_RESET_DELAY)
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen conndb->connect_delay = SQL_CONNECT_RESET_DELAY;
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen conn = sqlpool_find_available_connection(db, UINT_MAX,
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen /* still nothing. try creating new connections */
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen if (conn == NULL || !SQL_DB_IS_READY(conn->db))
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainendriver_sqlpool_get_sync_connection(struct sqlpool_db *db,
f81801789c71f64a2fc3c44d09f9864bbc68cd45Timo Sirainen unsigned int i, count;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (driver_sqlpool_get_connection(db, UINT_MAX, conn_r))
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen /* no idling connections, but maybe we can find one that's trying to
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen connect to server, and we can use it once it's finished */
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen conns = array_get(&db->all_connections, &count);
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen for (i = 0; i < count; i++) {
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen if (conns[i].db->state == SQL_DB_STATE_CONNECTING) {
ab1e5b156d1b5480d36ed6e8e06197339d803038Timo Sirainendriver_sqlpool_parse_hosts(struct sqlpool_db *db, const char *connect_string)
ab1e5b156d1b5480d36ed6e8e06197339d803038Timo Sirainen const char *const *args, *key, *value, *const *hostnamep;
ab1e5b156d1b5480d36ed6e8e06197339d803038Timo Sirainen ARRAY_TYPE(const_string) hostnames, connect_args;
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen /* connect string is a space separated list. it may contain
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen backend-specific strings which we'll pass as-is. we'll only care
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen about our own settings, plus the host settings. */
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen args = t_strsplit_spaces(connect_string, " ");
dad1d7b721e80a7e6c0282ace93aef86312fa579Timo Sirainen if (str_to_uint(value, &db->connection_limit) < 0) {
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen /* build a new connect string without our settings or hosts */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen connect_string = t_strarray_join(array_idx(&connect_args, 0), " ");
9bd08aa09ea0cbd7b221aae9fc0534eb762d3de6Timo Sirainen /* no hosts specified. create a default one. */
97144a346898fb62f9fae44fa5c076986553c66bTimo Sirainen host->connect_string = i_strdup(connect_string);
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen db->connection_limit = SQL_DEFAULT_CONNECTION_LIMIT;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenstatic void sqlpool_add_all_once(struct sqlpool_db *db)
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen host = sqlpool_find_host_with_least_connections(db, &host_idx);
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen (void)sqlpool_add_connection(db, host, host_idx);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainendriver_sqlpool_init(const char *connect_string, const struct sql_db *driver)
de9b2ee7878a73346ba0eee34798abb22ffcfcb6Timo Sirainen driver_sqlpool_parse_hosts(db, connect_string);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* connect to all databases so we can do load balancing immediately */
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainenstatic void driver_sqlpool_abort_requests(struct sqlpool_db *db)
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen struct sqlpool_request *request = db->requests_head;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void driver_sqlpool_deinit(struct sql_db *_db)
5bd1c1d4fe3265d5e6b6054044fd6d78e42c9d0aTimo Sirainen struct sqlpool_db *db = (struct sqlpool_db *)_db;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_foreach_modifiable(&db->all_connections, conn)
7707c4b35b868eda75b585c863d97726ff23f80fMartti Rannanjärvi array_foreach_modifiable(&db->hosts, host)
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen i_assert(array_count(&db->all_connections) == 0);
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainenstatic int driver_sqlpool_connect(struct sql_db *_db)
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen struct sqlpool_db *db = (struct sqlpool_db *)_db;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void driver_sqlpool_disconnect(struct sql_db *_db)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct sqlpool_db *db = (struct sqlpool_db *)_db;
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenstatic const char *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainendriver_sqlpool_escape_string(struct sql_db *_db, const char *string)
66ecc94150cbce23aad3240135e0782e0a74d479Timo Sirainen struct sqlpool_db *db = (struct sqlpool_db *)_db;
66ecc94150cbce23aad3240135e0782e0a74d479Timo Sirainen unsigned int i, count;
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen /* use the first ready connection */
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen conns = array_get(&db->all_connections, &count);
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen for (i = 0; i < count; i++) {
66ecc94150cbce23aad3240135e0782e0a74d479Timo Sirainen return sql_escape_string(conns[i].db, string);
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen /* no ready connections. just use the first one (we're guaranteed
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen to always have one) */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return sql_escape_string(conns[0].db, string);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstatic void driver_sqlpool_timeout(struct sqlpool_db *db)
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen struct sqlpool_request *request = db->requests_head;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (request->created + SQL_QUERY_TIMEOUT_SECS > ioloop_time)
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen "(no free connections for %u secs): %s",
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen (unsigned int)(ioloop_time - request->created),
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen "<transaction>");
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainendriver_sqlpool_prepend_request(struct sqlpool_db *db,
6307d76096764e66bddc63d4a3e5a1aa19cc528fJosef 'Jeff' Sipek DLLIST2_PREPEND(&db->requests_head, &db->requests_tail, request);
648d24583c1574441c4fa0331a90bd4d6e7996c5Timo Sirainen db->request_to = timeout_add(SQL_QUERY_TIMEOUT_SECS * 1000,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainendriver_sqlpool_append_request(struct sqlpool_db *db,
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainen DLLIST2_APPEND(&db->requests_head, &db->requests_tail, request);
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen db->request_to = timeout_add(SQL_QUERY_TIMEOUT_SECS * 1000,
763f83d3cc47bce05cbc396419c4db2b71dd8e68Timo Sirainendriver_sqlpool_query_callback(struct sql_result *result,
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen request->retry_count < array_count(&db->hosts)) {
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen db->driver->name, sql_result_get_error(result));
d0bbbc7057aa33b52ee378196dee7d773437468fTimo Sirainen if (driver_sqlpool_get_connection(request->db,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainendriver_sqlpool_query(struct sql_db *_db, const char *query,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen sql_query_callback_t *callback, void *context)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen struct sqlpool_db *db = (struct sqlpool_db *)_db;
ab70f55bb8d824ca1ed7c74196f2f502edd29cc7Timo Sirainen if (!driver_sqlpool_get_connection(db, UINT_MAX, &conn))
df6478c4cf605bd81b3891c148b84c14eb6c4035Timo Sirainen sql_query(conn->db, query, driver_sqlpool_query_callback,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void driver_sqlpool_exec(struct sql_db *_db, const char *query)
1c0590b2729567ad60dafde4d2c5f19635755a3dTimo Sirainenstatic struct sql_result *
1c0590b2729567ad60dafde4d2c5f19635755a3dTimo Sirainendriver_sqlpool_query_s(struct sql_db *_db, const char *query)
ba482d3624ca4f1b3d638e6e8470ba5134f21493Timo Sirainen struct sqlpool_db *db = (struct sqlpool_db *)_db;
ab70f55bb8d824ca1ed7c74196f2f502edd29cc7Timo Sirainen if (!driver_sqlpool_get_sync_connection(db, &conn)) {
ab70f55bb8d824ca1ed7c74196f2f502edd29cc7Timo Sirainen if (!driver_sqlpool_get_sync_connection(db, &conn))
ab70f55bb8d824ca1ed7c74196f2f502edd29cc7Timo Sirainendriver_sqlpool_transaction_begin(struct sql_db *_db)
ab70f55bb8d824ca1ed7c74196f2f502edd29cc7Timo Sirainen ctx = i_new(struct sqlpool_transaction_context, 1);
425cbcea60cf689b0069698c83f8bdc474d70693Timo Sirainen /* queue changes until commit. even if we did have a free connection
ab70f55bb8d824ca1ed7c74196f2f502edd29cc7Timo Sirainen now, don't use it or multiple open transactions could tie up all
ab70f55bb8d824ca1ed7c74196f2f502edd29cc7Timo Sirainen connections. */
114a0f74e0f825c6bd8aeadfafb248a030762a1fTimo Sirainen ctx->query_pool = pool_alloconly_create("sqlpool transaction", 1024);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainendriver_sqlpool_transaction_free(struct sqlpool_transaction_context *ctx)
ab70f55bb8d824ca1ed7c74196f2f502edd29cc7Timo Sirainendriver_sqlpool_commit_callback(const char *error,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainendriver_sqlpool_transaction_commit(struct sql_transaction_context *_ctx,
d0bbbc7057aa33b52ee378196dee7d773437468fTimo Sirainen struct sqlpool_db *db = (struct sqlpool_db *)_ctx->db;
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen ctx->commit_request = sqlpool_request_new(db, NULL);
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen if (driver_sqlpool_get_connection(db, UINT_MAX, &conn))
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen sqlpool_request_handle_transaction(conn->db, ctx);
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen driver_sqlpool_append_request(db, ctx->commit_request);
62cfc346eb7b0a4fd9e1ab6edd63b98711161229Timo Sirainendriver_sqlpool_transaction_commit_s(struct sql_transaction_context *_ctx,
62cfc346eb7b0a4fd9e1ab6edd63b98711161229Timo Sirainen const char **error_r)
62cfc346eb7b0a4fd9e1ab6edd63b98711161229Timo Sirainen struct sqlpool_db *db = (struct sqlpool_db *)_ctx->db;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (!driver_sqlpool_get_sync_connection(db, &conn)) {
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen conn_trans = driver_sqlpool_new_conn_trans(ctx, conn->db);
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen ret = sql_transaction_commit_s(&conn_trans, error_r);
dbd9604da561399cc6255289d5b6f6f662ab2d00Timo Sirainendriver_sqlpool_transaction_rollback(struct sql_transaction_context *_ctx)
dbd9604da561399cc6255289d5b6f6f662ab2d00Timo Sirainendriver_sqlpool_update(struct sql_transaction_context *_ctx, const char *query,
dbd9604da561399cc6255289d5b6f6f662ab2d00Timo Sirainen /* we didn't get a connection for transaction immediately.
dbd9604da561399cc6255289d5b6f6f662ab2d00Timo Sirainen queue updates until commit transfers all of these */
289064eb21595d3e4460439eccdc48232d13f5e1Timo Sirainen sql_transaction_add_query(&ctx->ctx, ctx->query_pool,
289064eb21595d3e4460439eccdc48232d13f5e1Timo Sirainenstatic const char *
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainen struct sqlpool_db *db = (struct sqlpool_db *)_db;
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainen unsigned int i, count;
044b0557e92ae0bb3b25af49d5468bad3d17db43Timo Sirainen /* use the first ready connection */
044b0557e92ae0bb3b25af49d5468bad3d17db43Timo Sirainen conns = array_get(&db->all_connections, &count);
044b0557e92ae0bb3b25af49d5468bad3d17db43Timo Sirainen for (i = 0; i < count; i++) {
289064eb21595d3e4460439eccdc48232d13f5e1Timo Sirainen return sql_escape_blob(conns[i].db, data, size);
289064eb21595d3e4460439eccdc48232d13f5e1Timo Sirainen /* no ready connections. just use the first one (we're guaranteed
289064eb21595d3e4460439eccdc48232d13f5e1Timo Sirainen to always have one) */