/** 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; }
/** 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; }
/** 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; }
/** 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; }