driver-mysql.c revision 5fbf8719b9ef072295c16bc4492f9f0ece92117d
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen/* Copyright (c) 2003-2010 Dovecot authors, see the included COPYING file */
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen const char *user, *password, *dbname, *host, *unix_socket;
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen const char *ssl_cert, *ssl_key, *ssl_ca, *ssl_ca_path, *ssl_cipher;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenextern const struct sql_result driver_mysql_result;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenextern const struct sql_result driver_mysql_error_result;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic const char *mysql_prefix(struct mysql_db *db)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return t_strdup_printf("mysql(%s)", db->host);
d1c2f6dd39ebb7f6b220ae2afda1162ba72ab43bTimo Sirainenstatic int driver_mysql_connect(struct sql_db *_db)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen unsigned long client_flags = db->client_flags;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen i_assert(db->api.state == SQL_DB_STATE_DISCONNECTED);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen sql_db_set_state(&db->api, SQL_DB_STATE_CONNECTING);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen mysql_options(db->mysql, MYSQL_READ_DEFAULT_FILE,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen mysql_options(db->mysql, MYSQL_READ_DEFAULT_GROUP,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen db->option_group != NULL ? db->option_group : "client");
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (!db->ssl_set && (db->ssl_ca != NULL || db->ssl_ca_path != NULL)) {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen mysql_ssl_set(db->mysql, db->ssl_key, db->ssl_cert,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen "(remove ssl_ca and ssl_ca_path settings)");
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* CLIENT_MULTI_RESULTS allows the use of stored procedures */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen failed = mysql_real_connect(db->mysql, host, db->user, db->password,
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen sql_db_set_state(&db->api, SQL_DB_STATE_DISCONNECTED);
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen i_error("%s: Connect failed to database (%s): %s - "
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen "waiting for %u seconds before retry",
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen mysql_error(db->mysql), db->api.connect_delay);
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen i_info("%s: Connected to database %s%s", mysql_prefix(db),
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen sql_db_set_state(&db->api, SQL_DB_STATE_IDLE);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstatic void driver_mysql_disconnect(struct sql_db *_db ATTR_UNUSED)
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainenstatic void driver_mysql_parse_connect_string(struct mysql_db *db,
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen const char **field;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen args = t_strsplit_spaces(connect_string, " ");
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen i_fatal("mysql: Missing value in connect string: %s",
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen i_fatal("mysql: Unknown connect string: %s", name);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen i_fatal("mysql: No hosts given in connect string");
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic struct sql_db *driver_mysql_init_v(const char *connect_string)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen pool = pool_alloconly_create("mysql driver", 1024);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen driver_mysql_parse_connect_string(db, connect_string);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic void driver_mysql_deinit_v(struct sql_db *_db)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen sql_db_set_state(&db->api, SQL_DB_STATE_DISCONNECTED);
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainenstatic int driver_mysql_do_query(struct mysql_db *db, const char *query)
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen sql_db_set_state(&db->api, SQL_DB_STATE_DISCONNECTED);
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainenstatic const char *
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainendriver_mysql_escape_string(struct sql_db *_db, const char *string)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (_db->state == SQL_DB_STATE_DISCONNECTED) {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* try connecting */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* FIXME: we don't have a valid connection, so fallback
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen to using default escaping. the next query will most
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen likely fail anyway so it shouldn't matter that much
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen what we return here.. Anyway, this API needs
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen changing so that the escaping function could already
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen fail the query reliably. */
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen len = mysql_real_escape_string(db->mysql, to, string, len);
8870854fbd44602a2d2174177c305f3570401a09Timo Sirainenstatic void driver_mysql_exec(struct sql_db *_db, const char *query)
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen mysql_prefix(db), query, mysql_error(db->mysql));
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic void driver_mysql_query(struct sql_db *db, const char *query,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen sql_query_callback_t *callback, void *context)
f0559b6bd1914e9118772d49415defe3dbb1817bTimo Sirainenstatic struct sql_result *
f0559b6bd1914e9118772d49415defe3dbb1817bTimo Sirainendriver_mysql_query_s(struct sql_db *_db, const char *query)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* query ok */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen result->affected_rows = mysql_affected_rows(db->mysql);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen result->result = mysql_store_result(db->mysql);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* Because we've enabled CLIENT_MULTI_RESULTS, we need to read
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen (ignore) extra results - there should not be any.
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ret is: -1 = done, >0 = error, 0 = more results. */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen while ((ret = mysql_next_result(db->mysql)) == 0) ;
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen (result->result != NULL || mysql_errno(db->mysql) == 0)) {
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainenstatic void driver_mysql_result_free(struct sql_result *_result)
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen struct mysql_result *result = (struct mysql_result *)_result;
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen i_assert(_result != &sql_not_connected_result);
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainenstatic int driver_mysql_result_next_row(struct sql_result *_result)
const char *field_name)
unsigned int idx)
unsigned long *lengths;
const char *field_name)
int idx;
if (idx < 0)
return NULL;
static struct sql_transaction_context *
const char *error;
unsigned int *affected_rows_r)
int ret = 0;
return ret;
const char **error_r)
int ret = 0;
return ret;
unsigned int *affected_rows)
void driver_mysql_init(void);
void driver_mysql_deinit(void);
void driver_mysql_init(void)
void driver_mysql_deinit(void)