Esempio n. 1
0
/**
 * \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;
}
Esempio n. 2
0
/*
 * 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;
}