/** * \brief Send a SQL query to the server. * * Send a SQL query to the database server. This methods tries to reconnect * to the server if the connection is gone and the auto_reconnect parameter is * enabled. It also issues a mysql_ping before the query to connect again after * a long waiting period because for some older mysql versions the auto reconnect * don't work sufficient. If auto_reconnect is enabled and the server supports it, * then the mysql_ping is probably not necessary, but its safer to do it in this * cases too. * * \param _h handle for the db * \param _s executed query * \return zero on success, negative value on failure */ static int db_mysql_submit_query(const db1_con_t* _h, const str* _s) { time_t t; int i, code; if (!_h || !_s || !_s->s) { LM_ERR("invalid parameter value\n"); return -1; } if (my_ping_interval) { t = time(0); if ((t - CON_TIMESTAMP(_h)) > my_ping_interval) { for (i=0; i < (db_mysql_auto_reconnect ? 3 : 1); i++) { if (mysql_ping(CON_CONNECTION(_h))) { LM_INFO("driver error on ping: %s\n", mysql_error(CON_CONNECTION(_h))); counter_inc(mysql_cnts_h.driver_err); } else { break; } } } /* * We're doing later a query anyway that will reset the timout of the server, * so it makes sense to set the timestamp value to the actual time in order * to prevent unnecessary pings. */ CON_TIMESTAMP(_h) = t; } /* When a server connection is lost and a query is attempted, most of * the time the query will return a CR_SERVER_LOST, then at the second * attempt to execute it, the mysql lib will reconnect and succeed. * However is a few cases, the first attempt returns CR_SERVER_GONE_ERROR * the second CR_SERVER_LOST and only the third succeeds. * Thus the 3 in the loop count. Increasing the loop count over this * value shouldn't be needed, but it doesn't hurt either, since the loop * will most of the time stop at the second or sometimes at the third * iteration. In the case of CR_SERVER_GONE_ERROR and CR_SERVER_LOST the * driver error counter is increased */ for (i=0; i < (db_mysql_auto_reconnect ? 3 : 1); i++) { if (mysql_real_query(CON_CONNECTION(_h), _s->s, _s->len) == 0) { return 0; } code = mysql_errno(CON_CONNECTION(_h)); if (code!=CR_SERVER_GONE_ERROR && code!=CR_SERVER_LOST && code!=CR_SSL_CONNECTION_ERROR && code!=CR_CONNECTION_ERROR && code!=CR_CONN_HOST_ERROR && code!=CR_SERVER_LOST_EXTENDED) { break; } counter_inc(mysql_cnts_h.driver_err); } LM_ERR("driver error on query: %s (%d)\n", mysql_error(CON_CONNECTION(_h)), mysql_errno(CON_CONNECTION(_h))); return -2; }
/* * Send an SQL query to the server */ static int db_mysql_submit_query(db_con_t* _h, const char* _s) { time_t t; int i, code; if ((!_h) || (!_s)) { LM_ERR("invalid parameter value\n"); return -1; } if (ping_interval) { t = time(0); if ((t - CON_TIMESTAMP(_h)) > ping_interval) { if (mysql_ping(CON_CONNECTION(_h))) { LM_DBG("mysql_ping failed\n"); } } CON_TIMESTAMP(_h) = t; } /* screws up the terminal when the query contains a BLOB :-( (by bogdan) * DBG("submit_query(): %s\n", _s); */ /* When a server connection is lost and a query is attempted, most of * the time the query will return a CR_SERVER_LOST, then at the second * attempt to execute it, the mysql lib will reconnect and succeed. * However is a few cases, the first attempt returns CR_SERVER_GONE_ERROR * the second CR_SERVER_LOST and only the third succeeds. * Thus the 3 in the loop count. Increasing the loop count over this * value shouldn't be needed, but it doesn't hurt either, since the loop * will most of the time stop at the second or sometimes at the third * iteration. */ for (i=0; i<(auto_reconnect ? 3 : 1); i++) { if (mysql_query(CON_CONNECTION(_h), _s)==0) { return 0; } code = mysql_errno(CON_CONNECTION(_h)); if (code != CR_SERVER_GONE_ERROR && code != CR_SERVER_LOST) { break; } } LM_ERR("driver error: %s\n", mysql_error(CON_CONNECTION(_h))); return -2; }