Ejemplo n.º 1
0
/** Call the driver's sql_query method, reconnecting if necessary.
 *
 * @param handle to query the database with. *handle should not be NULL, as this indicates
 *	  previous reconnection attempt has failed.
 * @param inst rlm_sql instance data.
 * @param query to execute. Should not be zero length.
 * @return RLM_SQL_OK on success, RLM_SQL_RECONNECT if a new handle is required (also sets *handle = NULL),
 *         RLM_SQL_QUERY_ERROR/RLM_SQL_ERROR on invalid query or connection error, RLM_SQL_DUPLICATE on constraints
 *         violation.
 */
sql_rcode_t rlm_sql_query(rlm_sql_handle_t **handle, rlm_sql_t *inst, char const *query)
{
	int ret = RLM_SQL_ERROR;
	int i, count;

	/* There's no query to run, return an error */
	if (query[0] == '\0') {
		ERROR("rlm_sql (%s): Zero length query", inst->config->xlat_name);
		return RLM_SQL_QUERY_ERROR;
	}

	/* There's no handle, we need a new one */
	if (!*handle) return RLM_SQL_RECONNECT;

	/*
	 *  inst->pool may be NULL is this function is called by mod_conn_create.
	 */
	count = inst->pool ? fr_connection_get_num(inst->pool) : 0;

	/*
	 *  Here we try with each of the existing connections, then try to create
	 *  a new connection, then give up.
	 */
	for (i = 0; i < (count + 1); i++) {
		DEBUG("rlm_sql (%s): Executing query: '%s'", inst->config->xlat_name, query);

		ret = (inst->module->sql_query)(*handle, inst->config, query);
		switch (ret) {
		case RLM_SQL_OK:
			break;

		/*
		 *	Run through all available sockets until we exhaust all existing
		 *	sockets in the pool and fail to establish a *new* connection.
		 */
		case RLM_SQL_RECONNECT:
			*handle = fr_connection_reconnect(inst->pool, *handle);
			/* Reconnection failed */
			if (!*handle) return RLM_SQL_RECONNECT;
			/* Reconnection succeeded, try again with the new handle */
			continue;

		case RLM_SQL_QUERY_ERROR:
		case RLM_SQL_ERROR:
			rlm_sql_query_error(*handle, inst);
			break;

		case RLM_SQL_DUPLICATE:
			rlm_sql_query_debug(*handle, inst);
			break;

		}

		return ret;
	}

	ERROR("rlm_sql (%s): Hit reconnection limit", inst->config->xlat_name);

	return RLM_SQL_ERROR;
}
Ejemplo n.º 2
0
/** Call the driver's sql_select_query method, reconnecting if necessary.
 *
 * @note Caller must call ``(inst->module->sql_finish_select_query)(handle, inst->config);``
 *	after they're done with the result.
 *
 * @param inst #rlm_sql_t instance data.
 * @param request Current request.
 * @param handle to query the database with. *handle should not be NULL, as this indicates
 *	  previous reconnection attempt has failed.
 * @param query to execute. Should not be zero length.
 * @return
 *	- #RLM_SQL_OK on success.
 *	- #RLM_SQL_RECONNECT if a new handle is required (also sets *handle = NULL).
 *	- #RLM_SQL_QUERY_INVALID, #RLM_SQL_ERROR on invalid query or connection error.
 */
sql_rcode_t rlm_sql_select_query(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t **handle,  char const *query)
{
	int ret = RLM_SQL_ERROR;
	int i, count;

	/* Caller should check they have a valid handle */
	rad_assert(*handle);

	/* There's no query to run, return an error */
	if (query[0] == '\0') {
		if (request) REDEBUG("Zero length query");

		return RLM_SQL_QUERY_INVALID;
	}

	/*
	 *  inst->pool may be NULL is this function is called by mod_conn_create.
	 */
	count = inst->pool ? fr_connection_get_num(inst->pool) : 0;

	/*
	 *  For sanity, for when no connections are viable, and we can't make a new one
	 */
	for (i = 0; i < (count + 1); i++) {
		ROPTIONAL(RDEBUG2, DEBUG2, "Executing select query: %s", query);

		ret = (inst->module->sql_select_query)(*handle, inst->config, query);
		switch (ret) {
		case RLM_SQL_OK:
			break;

		/*
		 *	Run through all available sockets until we exhaust all existing
		 *	sockets in the pool and fail to establish a *new* connection.
		 */
		case RLM_SQL_RECONNECT:
			*handle = fr_connection_reconnect(inst->pool, *handle);
			/* Reconnection failed */
			if (!*handle) return RLM_SQL_RECONNECT;
			/* Reconnection succeeded, try again with the new handle */
			continue;

		case RLM_SQL_QUERY_INVALID:
		case RLM_SQL_ERROR:
		default:
			rlm_sql_print_error(inst, request, *handle, false);
			(inst->module->sql_finish_select_query)(*handle, inst->config);
			break;
		}

		return ret;
	}

	ROPTIONAL(RERROR, ERROR, "Hit reconnection limit");

	return RLM_SQL_ERROR;
}
Ejemplo n.º 3
0
/** Call the driver's sql_query method, reconnecting if necessary.
 *
 * @param handle to query the database with. *handle should not be NULL, as this indicates
 *	  previous reconnection attempt has failed.
 * @param inst rlm_sql instance data.
 * @param query to execute. Should not be zero length.
 * @return RLM_SQL_OK on success, RLM_SQL_RECONNECT if a new handle is required (also sets *handle = NULL),
 *         RLM_SQL_QUERY_ERROR/RLM_SQL_ERROR on invalid query or connection error, RLM_SQL_DUPLICATE on constraints
 *         violation.
 */
sql_rcode_t rlm_sql_query(rlm_sql_handle_t **handle, rlm_sql_t *inst, char const *query)
{
	int ret = RLM_SQL_ERROR;
	int i;

	/* There's no query to run, return an error */
	if (query[0] == '\0') return RLM_SQL_QUERY_ERROR;

	/* There's no handle, we need a new one */
	if (!*handle) return RLM_SQL_RECONNECT;

	/* For sanity, for when no connections are viable, and we can't make a new one */
	for (i = fr_connection_get_num(inst->pool); i >= 0; i--) {
		DEBUG("rlm_sql (%s): Executing query: '%s'", inst->config->xlat_name, query);

		ret = (inst->module->sql_query)(*handle, inst->config, query);
		switch (ret) {
		case RLM_SQL_OK:
			break;

		/*
		 *	Run through all available sockets until we exhaust all existing
		 *	sockets in the pool and fail to establish a *new* connection.
		 */
		case RLM_SQL_RECONNECT:
			*handle = fr_connection_reconnect(inst->pool, *handle);
			/* Reconnection failed */
			if (!*handle) return RLM_SQL_RECONNECT;
			/* Reconnection succeeded, try again with the new handle */
			continue;

		case RLM_SQL_QUERY_ERROR:
		case RLM_SQL_ERROR:
			rlm_sql_query_error(*handle, inst);
			break;

		case RLM_SQL_DUPLICATE:
			rlm_sql_query_debug(*handle, inst);
			break;

		}

		return ret;
	}

	ERROR("rlm_sql (%s): Hit reconnection limit", inst->config->xlat_name);

	return RLM_SQL_ERROR;
}
Ejemplo n.º 4
0
/** Call the driver's sql_query method, reconnecting if necessary.
 *
 * @note Caller must call ``(inst->module->sql_finish_query)(handle, inst->config);``
 *	after they're done with the result.
 *
 * @param handle to query the database with. *handle should not be NULL, as this indicates
 * 	previous reconnection attempt has failed.
 * @param request Current request.
 * @param inst #rlm_sql_t instance data.
 * @param query to execute. Should not be zero length.
 * @return
 *	- #RLM_SQL_OK on success.
 *	- #RLM_SQL_RECONNECT if a new handle is required (also sets *handle = NULL).
 *	- #RLM_SQL_QUERY_INVALID, #RLM_SQL_ERROR on invalid query or connection error.
 *	- #RLM_SQL_ALT_QUERY on constraints violation.
 */
sql_rcode_t rlm_sql_query(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t **handle, char const *query)
{
	int ret = RLM_SQL_ERROR;
	int i, count;

	/* Caller should check they have a valid handle */
	rad_assert(*handle);

	/* There's no query to run, return an error */
	if (query[0] == '\0') {
		if (request) REDEBUG("Zero length query");
		return RLM_SQL_QUERY_INVALID;
	}

	/*
	 *  inst->pool may be NULL is this function is called by mod_conn_create.
	 */
	count = inst->pool ? fr_connection_get_num(inst->pool) : 0;

	/*
	 *  Here we try with each of the existing connections, then try to create
	 *  a new connection, then give up.
	 */
	for (i = 0; i < (count + 1); i++) {
		ROPTIONAL(RDEBUG2, DEBUG2, "Executing query: %s", query);

		ret = (inst->module->sql_query)(*handle, inst->config, query);
		switch (ret) {
		case RLM_SQL_OK:
			break;

		/*
		 *	Run through all available sockets until we exhaust all existing
		 *	sockets in the pool and fail to establish a *new* connection.
		 */
		case RLM_SQL_RECONNECT:
			*handle = fr_connection_reconnect(inst->pool, *handle);
			/* Reconnection failed */
			if (!*handle) return RLM_SQL_RECONNECT;
			/* Reconnection succeeded, try again with the new handle */
			continue;

		/*
		 *	These are bad and should make rlm_sql return invalid
		 */
		case RLM_SQL_QUERY_INVALID:
			rlm_sql_print_error(inst, request, *handle, false);
			(inst->module->sql_finish_query)(*handle, inst->config);
			break;

		/*
		 *	Server or client errors.
		 *
		 *	If the driver claims to be able to distinguish between
		 *	duplicate row errors and other errors, and we hit a
		 *	general error treat it as a failure.
		 *
		 *	Otherwise rewrite it to RLM_SQL_ALT_QUERY.
		 */
		case RLM_SQL_ERROR:
			if (inst->module->flags & RLM_SQL_RCODE_FLAGS_ALT_QUERY) {
				rlm_sql_print_error(inst, request, *handle, false);
				(inst->module->sql_finish_query)(*handle, inst->config);
				break;
			}
			ret = RLM_SQL_ALT_QUERY;
			/* FALL-THROUGH */

		/*
		 *	Driver suggested using an alternative query
		 */
		case RLM_SQL_ALT_QUERY:
			rlm_sql_print_error(inst, request, *handle, true);
			(inst->module->sql_finish_query)(*handle, inst->config);
			break;

		}

		return ret;
	}

	ROPTIONAL(RERROR, ERROR, "Hit reconnection limit");

	return RLM_SQL_ERROR;
}