return RLM_SQL_OK;
}
-static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
- rlm_sql_cassandra_conn_t *conn = handle->conn;
- rlm_sql_cassandra_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_cassandra_t);
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
+ rlm_sql_cassandra_conn_t *conn = query_ctx->handle->conn;
+ rlm_sql_cassandra_t *inst = talloc_get_type_abort(query_ctx->handle->inst->driver_submodule->data, rlm_sql_cassandra_t);
CassStatement *statement;
CassFuture *future;
CassError ret;
- statement = cass_statement_new_n(query, talloc_array_length(query) - 1, 0);
+ statement = cass_statement_new_n(query_ctx->query_str, talloc_array_length(query_ctx->query_str) - 1, 0);
if (inst->consistency_str) cass_statement_set_consistency(statement, inst->consistency);
future = cass_session_execute(inst->session, statement);
switch (ret) {
case CASS_ERROR_SERVER_SYNTAX_ERROR:
case CASS_ERROR_SERVER_INVALID_QUERY:
- return RLM_SQL_QUERY_INVALID;
+ query_ctx->rcode = RLM_SQL_QUERY_INVALID;
+ RETURN_MODULE_INVALID;
default:
- return RLM_SQL_ERROR;
+ query_ctx->rcode = RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
}
conn->result = cass_future_get_result(future);
cass_future_free(future);
- return RLM_SQL_OK;
+ query_ctx->rcode = RLM_SQL_OK;
+ RETURN_MODULE_OK;
}
static int sql_num_fields(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
return RLM_SQL_OK;
}
-static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
{
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
SQLRETURN row;
rlm_sql_db2_conn_t *conn;
- conn = handle->conn;
+ conn = query_ctx->handle->conn;
/* allocate handle for statement */
SQLAllocHandle(SQL_HANDLE_STMT, conn->dbc_handle, &(conn->stmt));
/* execute query */
{
SQLCHAR *db2_query;
- memcpy(&db2_query, &query, sizeof(query));
+ memcpy(&db2_query, &query_ctx->query_str, sizeof(query_ctx->query_str));
row = SQLExecDirect(conn->stmt, db2_query, SQL_NTS);
if(row != SQL_SUCCESS) {
/* XXX Check if row means we should return RLM_SQL_RECONNECT */
ERROR("Could not execute statement \"%s\"", query);
- return RLM_SQL_ERROR;
+ query_ctx->rcode = RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL
}
}
- return RLM_SQL_OK;
-}
-
-static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query)
-{
- return sql_query(handle, config, query);
+ query_ctx->rcode = RLM_SQL_OK;
+ RETURN_MODULE_OK;
}
static int sql_num_fields(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
},
.sql_socket_init = sql_socket_init,
.sql_query = sql_query,
- .sql_select_query = sql_select_query,
+ .sql_select_query = sql_query,
.sql_num_fields = sql_num_fields,
.sql_affected_rows = sql_affected_rows,
.sql_fields = sql_fields,
return 0;
}
-/** Issue a non-SELECT query (ie: update/delete/insert) to the database.
+/** Issue a query to the database.
*
*/
-static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
- rlm_sql_firebird_conn_t *conn = handle->conn;
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
+ rlm_sql_firebird_conn_t *conn = query_ctx->handle->conn;
int deadlock = 0;
* Try again query when deadlock, because in any case it
* will be retried.
*/
- if (fb_sql_query(conn, query)) {
+ if (fb_sql_query(conn, query_ctx->query_str)) {
/* but may be lost for short sessions */
if ((conn->sql_code == DEADLOCK_SQL_CODE) &&
!deadlock) {
- DEBUG("conn_id deadlock. Retry query %s", query);
+ DEBUG("conn_id deadlock. Retry query %s", query_ctx->query_str);
/*
* @todo For non READ_COMMITED transactions put
}
ERROR("conn_id rlm_sql_firebird,sql_query error: sql_code=%li, error='%s', query=%s",
- (long int) conn->sql_code, conn->error, query);
+ (long int) conn->sql_code, conn->error, query_ctx->query_str);
if (conn->sql_code == DOWN_SQL_CODE) {
pthread_mutex_unlock(&conn->mut);
- return RLM_SQL_RECONNECT;
+ query_ctx->rcode = RLM_SQL_RECONNECT;
+ RETURN_MODULE_FAIL;
}
/* Free problem query */
//assume the network is down if rollback had failed
ERROR("Fail to rollback transaction after previous error: %s", conn->error);
- return RLM_SQL_RECONNECT;
+ query_ctx->rcode = RLM_SQL_RECONNECT;
+ RETURN_MODULE_FAIL;
}
// conn->in_use=0;
- return RLM_SQL_ERROR;
+ query_ctx->rcode = RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
if (conn->statement_type != isc_info_sql_stmt_select) {
- if (fb_commit(conn)) return RLM_SQL_ERROR; /* fb_commit unlocks the mutex */
+ if (fb_commit(conn)) {
+ query_ctx->rcode = RLM_SQL_ERROR; /* fb_commit unlocks the mutex */
+ RETURN_MODULE_FAIL;
+ }
} else {
pthread_mutex_unlock(&conn->mut);
}
- return 0;
-}
-
-/** Issue a select query to the database.
- *
- */
-static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query)
-{
- return sql_query(handle, config, query);
+ query_ctx->rcode = RLM_SQL_OK;
+ RETURN_MODULE_OK;
}
/** Returns number of columns from query.
},
.sql_socket_init = sql_socket_init,
.sql_query = sql_query,
- .sql_select_query = sql_select_query,
+ .sql_select_query = sql_query,
.sql_num_fields = sql_num_fields,
.sql_num_rows = sql_num_rows,
.sql_affected_rows = sql_affected_rows,
* the database.
*
*************************************************************************/
-static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
- rlm_sql_freetds_conn_t *conn = handle->conn;
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
+ rlm_sql_freetds_conn_t *conn = query_ctx->handle->conn;
CS_RETCODE results_ret;
CS_INT result_type;
+ query_ctx->rcode = RLM_SQL_ERROR;
+
/*
* Reset rows_affected in case the query fails.
* Prevents accidentally returning the rows_affected from a previous query.
if (ct_cmd_alloc(conn->db, &conn->command) != CS_SUCCEED) {
ERROR("Unable to allocate command structure (ct_cmd_alloc())");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
- if (ct_command(conn->command, CS_LANG_CMD, query, CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ if (ct_command(conn->command, CS_LANG_CMD, query_ctx->query_str, CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
ERROR("Unable to initialise command structure (ct_command())");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
if (ct_send(conn->command) != CS_SUCCEED) {
ERROR("Unable to send command (ct_send())");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
/*
}
ERROR("Result failure or unexpected result type from query");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
} else {
switch (results_ret) {
if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) {
INFO("Cleaning up");
-
- return RLM_SQL_RECONNECT;
+ reconnect:
+ query_ctx->rcode = RLM_SQL_RECONNECT;
+ RETURN_MODULE_FAIL;
}
conn->command = NULL;
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
default:
ERROR("Unexpected return value from ct_results()");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
}
if (ct_res_info(conn->command, CS_ROW_COUNT, &conn->rows_affected, CS_UNUSED, NULL) != CS_SUCCEED) {
ERROR("rlm_sql_freetds: error retrieving row count");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
/*
if (result_type != CS_CMD_DONE) {
ERROR("Result failure or unexpected result type from query");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
} else {
switch (results_ret) {
case CS_FAIL: /* Serious failure, freetds requires us to cancel and maybe even close db */
ERROR("Failure retrieving query results");
- if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) return RLM_SQL_RECONNECT;
+ if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) goto reconnect;
conn->command = NULL;
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
default:
ERROR("Unexpected return value from ct_results()");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
}
switch (results_ret) {
case CS_FAIL: /* Serious failure, freetds requires us to cancel and maybe even close db */
ERROR("Failure retrieving query results");
- if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) return RLM_SQL_RECONNECT;
+ if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) goto reconnect;
conn->command = NULL;
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
case CS_END_RESULTS: /* This is where we want to end up */
break;
default:
ERROR("Unexpected return value from ct_results()");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
- return RLM_SQL_OK;
+ query_ctx->rcode = RLM_SQL_OK;
+ RETURN_MODULE_OK;
}
/*************************************************************************
* consecutive rows will be discarded.
*
*/
-static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
- rlm_sql_freetds_conn_t *conn = handle->conn;
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
+ rlm_sql_freetds_conn_t *conn = query_ctx->handle->conn;
CS_RETCODE results_ret;
CS_INT result_type;
int colcount,i;
char **rowdata;
+ query_ctx->rcode = RLM_SQL_ERROR;
+
if (!conn->db) {
ERROR("socket not connected");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
if (ct_cmd_alloc(conn->db, &conn->command) != CS_SUCCEED) {
ERROR("unable to allocate command structure (ct_cmd_alloc())");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
- if (ct_command(conn->command, CS_LANG_CMD, query, CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ if (ct_command(conn->command, CS_LANG_CMD, query_ctx->query_str, CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
ERROR("unable to initiate command structure (ct_command()");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
if (ct_send(conn->command) != CS_SUCCEED) {
ERROR("unable to send command (ct_send())");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
results_ret = ct_results(conn->command, &result_type);
descriptor.count = 1; /* Fetch one row of data */
descriptor.locale = NULL; /* Don't do NLS stuff */
- colcount = sql_num_fields(handle, config); /* Get number of elements in row result */
+ colcount = sql_num_fields(query_ctx->handle, &query_ctx->inst->config); /* Get number of elements in row result */
rowdata = talloc_zero_array(conn, char *, colcount + 1); /* Space for pointers */
rowdata[colcount] = NULL;
ERROR("ct_bind() failed)");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
}
default:
ERROR("unexpected result type from query");
- sql_finish_select_query(handle, config);
+ sql_finish_select_query(query_ctx->handle, &query_ctx->inst->config);
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
break;
if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) {
ERROR("cleaning up");
- return RLM_SQL_RECONNECT;
+ query_ctx->rcode = RLM_SQL_RECONNECT;
+ RETURN_MODULE_FAIL;
}
conn->command = NULL;
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
default:
ERROR("unexpected return value from ct_results()");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
- return RLM_SQL_OK;
+ query_ctx->rcode = RLM_SQL_OK;
+ RETURN_MODULE_OK;
}
static int sql_num_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
{
rlm_sql_freetds_conn_t *conn;
unsigned int timeout_ms = fr_time_delta_to_msec(timeout);
+ fr_sql_query_t *query_ctx;
+ rlm_rcode_t p_result;
MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_freetds_conn_t));
talloc_set_destructor(conn, _sql_socket_destructor);
* sql statement when we first open the connection.
*/
snprintf(database, sizeof(database), "USE %s;", config->sql_db);
- if (sql_query(handle, config, database) != RLM_SQL_OK) {
+ MEM(query_ctx = fr_sql_query_alloc(NULL, handle->inst, handle, database, SQL_QUERY_OTHER));
+ if ((sql_query(&p_result, NULL, NULL, query_ctx) == UNLANG_ACTION_CALCULATE_RESULT) &&
+ (query_ctx->rcode != RLM_SQL_OK)) {
goto error;
}
-
- sql_finish_query(handle, config);
+ talloc_free(query_ctx);
}
return RLM_SQL_OK;
return RLM_SQL_OK;
}
-static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
- rlm_sql_mysql_conn_t *conn = talloc_get_type_abort(handle->conn, rlm_sql_mysql_conn_t);
- sql_rcode_t rcode;
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
+ rlm_sql_mysql_conn_t *conn = talloc_get_type_abort(query_ctx->handle->conn, rlm_sql_mysql_conn_t);
char const *info;
- mysql_query(conn->sock, query);
- rcode = sql_check_error(conn->sock, 0);
- if (rcode != RLM_SQL_OK) return rcode;
+ mysql_query(conn->sock, query_ctx->query_str);
+ query_ctx->rcode = sql_check_error(conn->sock, 0);
+ if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL;
/* Only returns non-null string for INSERTS */
info = mysql_info(conn->sock);
if (info) DEBUG2("%s", info);
- return RLM_SQL_OK;
+ RETURN_MODULE_OK;
}
static sql_rcode_t sql_store_result(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
return mysql_field_count(conn->sock);
}
-static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
{
- sql_rcode_t rcode;
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
- rcode = sql_query(handle, config, query);
- if (rcode != RLM_SQL_OK) return rcode;
+ sql_query(p_result, NULL, request, query_ctx);
+ if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL;
- return sql_store_result(handle, config);
+ query_ctx->rcode = sql_store_result(query_ctx->handle, &query_ctx->inst->config);
+ if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL;
+ RETURN_MODULE_OK;
}
static int sql_num_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
return 0;
}
-static sql_rcode_t sql_query(UNUSED rlm_sql_handle_t * handle,
- UNUSED rlm_sql_config_t const *config, UNUSED char const *query)
+static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
- return 0;
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
+ query_ctx->rcode = RLM_SQL_OK;
+ RETURN_MODULE_OK;
}
static int sql_num_fields(UNUSED rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t const *config)
return 0;
}
-static sql_rcode_t sql_select_query(UNUSED rlm_sql_handle_t *handle,
- UNUSED rlm_sql_config_t const *config, UNUSED char const *query)
-{
- return 0;
-}
-
static int sql_num_rows(UNUSED rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t const *config)
{
return 0;
},
.sql_socket_init = sql_socket_init,
.sql_query = sql_query,
- .sql_select_query = sql_select_query,
+ .sql_select_query = sql_query,
.sql_num_fields = sql_num_fields,
.sql_num_rows = sql_num_rows,
.sql_fetch_row = sql_fetch_row,
return RLM_SQL_OK;
}
-static sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
int status;
- rlm_sql_oracle_conn_t *conn = handle->conn;
+ rlm_sql_oracle_conn_t *conn = query_ctx->handle->conn;
if (!conn->ctx) {
ERROR("Socket not connected");
- return RLM_SQL_RECONNECT;
+ query_ctx->rcode = RLM_SQL_RECONNECT;
+ RETURN_MODULE_FAIL;
}
- if (OCIStmtPrepare2(conn->ctx, &conn->query, conn->error, (const OraText *)query, strlen(query),
+ query_ctx->rcode = RLM_SQL_ERROR;
+
+ if (OCIStmtPrepare2(conn->ctx, &conn->query, conn->error, (const OraText *)query_ctx->query_str, strlen(query_ctx->query_str),
NULL, 0, OCI_NTV_SYNTAX, OCI_DEFAULT)) {
ERROR("prepare failed in sql_query");
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
status = OCIStmtExecute(conn->ctx, conn->query, conn->error, 1, 0,
NULL, NULL, OCI_COMMIT_ON_SUCCESS);
- if (status == OCI_SUCCESS) return RLM_SQL_OK;
+ if (status == OCI_SUCCESS) {
+ query_ctx->rcode = RLM_SQL_OK;
+ RETURN_MODULE_OK;
+ }
if (status == OCI_ERROR) {
ERROR("execute query failed in sql_query");
- return sql_check_reconnect(handle, config);
+ query_ctx->rcode = sql_check_reconnect(query_ctx->handle, &query_ctx->inst->config);
}
- return RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
-static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
int status;
- char **row;
+ char **row = NULL;
int i;
OCIParam *param;
sb2 *ind;
- rlm_sql_oracle_conn_t *conn = handle->conn;
+ rlm_sql_oracle_conn_t *conn = query_ctx->handle->conn;
- if (OCIStmtPrepare2(conn->ctx, &conn->query, conn->error, (const OraText *)query, strlen(query),
+ if (OCIStmtPrepare2(conn->ctx, &conn->query, conn->error, (const OraText *)query_ctx->query_str, strlen(query_ctx->query_str),
NULL, 0, OCI_NTV_SYNTAX, OCI_DEFAULT)) {
ERROR("prepare failed in sql_select_query");
- return RLM_SQL_ERROR;
+ goto error;
}
/*
* Retrieve a single row
*/
status = OCIStmtExecute(conn->ctx, conn->query, conn->error, 0, 0, NULL, NULL, OCI_DEFAULT);
- if (status == OCI_NO_DATA) return RLM_SQL_OK;
+ if (status == OCI_NO_DATA) goto finish;
if (status != OCI_SUCCESS) {
ERROR("query failed in sql_select_query");
- return sql_check_reconnect(handle, config);
+ query_ctx->rcode = sql_check_reconnect(query_ctx->handle, &query_ctx->inst->config);
+ RETURN_MODULE_FAIL;
}
/*
* the number of columns won't change.
*/
if (conn->col_count == 0) {
- conn->col_count = sql_num_fields(handle, config);
+ conn->col_count = sql_num_fields(query_ctx->handle, &query_ctx->inst->config);
- if (conn->col_count == 0) return RLM_SQL_ERROR;
+ if (conn->col_count == 0) goto error;
}
MEM(row = talloc_zero_array(conn, char*, conn->col_count + 1));
conn->row = row;
conn->ind = ind;
- return RLM_SQL_OK;
+finish:
+ query_ctx->rcode = RLM_SQL_OK;
+ RETURN_MODULE_OK;
error:
talloc_free(row);
- return RLM_SQL_ERROR;
+ query_ctx->rcode = RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
static int sql_num_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
return 0;
}
-static CC_HINT(nonnull) sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config,
- char const *query)
+static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
- rlm_sql_postgres_conn_t *conn = handle->conn;
- rlm_sql_postgresql_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_postgresql_t);
- fr_time_delta_t timeout = config->query_timeout;
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
+ rlm_sql_postgres_conn_t *conn = query_ctx->handle->conn;
+ rlm_sql_postgresql_t *inst = talloc_get_type_abort(query_ctx->inst->driver_submodule->data, rlm_sql_postgresql_t);
+ fr_time_delta_t timeout = query_ctx->inst->config.query_timeout;
fr_time_t start;
int sockfd;
PGresult *tmp_result;
if (!conn->db) {
ERROR("Socket not connected");
- return RLM_SQL_RECONNECT;
+ reconnect:
+ query_ctx->rcode = RLM_SQL_RECONNECT;
+ RETURN_MODULE_FAIL;
}
sockfd = PQsocket(conn->db);
if (sockfd < 0) {
ERROR("Unable to obtain socket: %s", PQerrorMessage(conn->db));
- return RLM_SQL_RECONNECT;
+ goto reconnect;
}
- if (!PQsendQuery(conn->db, query)) {
+ if (!PQsendQuery(conn->db, query_ctx->query_str)) {
ERROR("Failed to send query: %s", PQerrorMessage(conn->db));
- return RLM_SQL_RECONNECT;
+ goto reconnect;
}
/*
FD_ZERO(&read_fd);
FD_SET(sockfd, &read_fd);
- if (fr_time_delta_ispos(config->query_timeout)) {
+ if (fr_time_delta_ispos(timeout)) {
elapsed = fr_time_sub(fr_time(), start);
if (fr_time_delta_gteq(elapsed, timeout)) goto too_long;
}
- r = select(sockfd + 1, &read_fd, NULL, NULL, fr_time_delta_ispos(config->query_timeout) ?
+ r = select(sockfd + 1, &read_fd, NULL, NULL, fr_time_delta_ispos(timeout) ?
&fr_time_delta_to_timeval(fr_time_delta_sub(timeout, elapsed)) : NULL);
if (r == 0) {
too_long:
- ERROR("Socket read timeout after %d seconds", (int) fr_time_delta_to_sec(config->query_timeout));
- return RLM_SQL_RECONNECT;
+ ERROR("Socket read timeout after %d seconds", (int) fr_time_delta_to_sec(timeout));
+ goto reconnect;
}
if (r < 0) {
if (errno == EINTR) continue;
ERROR("Failed in select: %s", fr_syserror(errno));
- return RLM_SQL_RECONNECT;
+ goto reconnect;
}
if (!PQconsumeInput(conn->db)) {
ERROR("Failed reading input: %s", PQerrorMessage(conn->db));
- return RLM_SQL_RECONNECT;
+ goto reconnect;
}
}
*/
if (!conn->result) {
ERROR("Failed getting query result: %s", PQerrorMessage(conn->db));
- return RLM_SQL_RECONNECT;
+ goto reconnect;
}
status = PQresultStatus(conn->result);
break;
}
- return sql_classify_error(inst, status, conn->result);
-}
-
-static sql_rcode_t sql_select_query(rlm_sql_handle_t * handle, rlm_sql_config_t const *config, char const *query)
-{
- return sql_query(handle, config, query);
+ query_ctx->rcode = sql_classify_error(inst, status, conn->result);
+ if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL;
+ RETURN_MODULE_OK;
}
static sql_rcode_t sql_fields(char const **out[], rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
.flags = RLM_SQL_RCODE_FLAGS_ALT_QUERY,
.sql_socket_init = sql_socket_init,
.sql_query = sql_query,
- .sql_select_query = sql_select_query,
+ .sql_select_query = sql_query,
.sql_num_fields = sql_num_fields,
.sql_fields = sql_fields,
.sql_fetch_row = sql_fetch_row,
return RLM_SQL_OK;
}
-static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
- rlm_sql_sqlite_conn_t *conn = handle->conn;
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
+ rlm_sql_sqlite_conn_t *conn = query_ctx->handle->conn;
char const *z_tail;
int status;
#ifdef HAVE_SQLITE3_PREPARE_V2
- status = sqlite3_prepare_v2(conn->db, query, strlen(query), &conn->statement, &z_tail);
+ status = sqlite3_prepare_v2(conn->db, query_ctx->query_str, strlen(query_ctx->query_str), &conn->statement, &z_tail);
#else
- status = sqlite3_prepare(conn->db, query, strlen(query), &conn->statement, &z_tail);
+ status = sqlite3_prepare(conn->db, query_ctx->query_str, strlen(query_ctx->query_str), &conn->statement, &z_tail);
#endif
conn->col_count = 0;
- return sql_check_error(conn->db, status);
+ query_ctx->rcode = sql_check_error(conn->db, status);
+ if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL;
+ RETURN_MODULE_OK;
}
-static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
-
- sql_rcode_t rcode;
- rlm_sql_sqlite_conn_t *conn = handle->conn;
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
+ rlm_sql_sqlite_conn_t *conn = query_ctx->handle->conn;
char const *z_tail;
int status;
#ifdef HAVE_SQLITE3_PREPARE_V2
- status = sqlite3_prepare_v2(conn->db, query, strlen(query), &conn->statement, &z_tail);
+ status = sqlite3_prepare_v2(conn->db, query_ctx->query_str, strlen(query_ctx->query_str), &conn->statement, &z_tail);
#else
- status = sqlite3_prepare(conn->db, query, strlen(query), &conn->statement, &z_tail);
+ status = sqlite3_prepare(conn->db, query_ctx->query_str, strlen(query_ctx->query_str), &conn->statement, &z_tail);
#endif
- rcode = sql_check_error(conn->db, status);
- if (rcode != RLM_SQL_OK) return rcode;
+ query_ctx->rcode = sql_check_error(conn->db, status);
+ if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL;
status = sqlite3_step(conn->statement);
- return sql_check_error(conn->db, status);
+ query_ctx->rcode = sql_check_error(conn->db, status);
+ if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL;
+ RETURN_MODULE_OK;
}
static int sql_num_fields(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
return RLM_SQL_OK;
}
-static sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
- rlm_sql_unixodbc_conn_t *conn = handle->conn;
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
+ rlm_sql_unixodbc_conn_t *conn = query_ctx->handle->conn;
long err_handle;
- int state;
/* Executing query */
- err_handle = SQLExecDirect(conn->stmt, UNCONST(SQLCHAR *, query), strlen(query));
- if ((state = sql_check_error(err_handle, handle, config))) {
- if(state == RLM_SQL_RECONNECT) {
+ err_handle = SQLExecDirect(conn->stmt, UNCONST(SQLCHAR *, query_ctx->query_str), strlen(query_ctx->query_str));
+ if ((query_ctx->rcode = sql_check_error(err_handle, query_ctx->handle, &query_ctx->inst->config))) {
+ if(query_ctx->rcode == RLM_SQL_RECONNECT) {
DEBUG("rlm_sql will attempt to reconnect");
}
- return state;
+ RETURN_MODULE_FAIL;
}
- return 0;
+ RETURN_MODULE_OK;
}
-static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query)
+static unlang_action_t sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
{
- rlm_sql_unixodbc_conn_t *conn = handle->conn;
+ fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
+ rlm_sql_unixodbc_conn_t *conn = query_ctx->handle->conn;
SQLINTEGER i;
SQLLEN len;
int colcount;
- int state;
/* Only state = 0 means success */
- if ((state = sql_query(handle, config, query))) {
- return state;
- }
+ if ((sql_query(p_result, NULL, request, query_ctx) == UNLANG_ACTION_CALCULATE_RESULT) &&
+ (query_ctx->rcode != RLM_SQL_OK)) RETURN_MODULE_FAIL;
- colcount = sql_num_fields(handle, config);
+ colcount = sql_num_fields(query_ctx->handle, &query_ctx->inst->config);
if (colcount < 0) {
- return RLM_SQL_ERROR;
+ query_ctx->rcode = RLM_SQL_ERROR;
+ RETURN_MODULE_FAIL;
}
/* Reserving memory for result */
SQLBindCol(conn->stmt, i, SQL_C_CHAR, (SQLCHAR *)conn->row[i - 1], len, NULL);
}
- return RLM_SQL_OK;
+ RETURN_MODULE_OK;
}
static int sql_num_fields(rlm_sql_handle_t *handle, rlm_sql_config_t const *config)
sql_rcode_t (*sql_socket_init)(rlm_sql_handle_t *handle, rlm_sql_config_t const *config,
fr_time_delta_t timeout);
- sql_rcode_t (*sql_query)(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query);
- sql_rcode_t (*sql_select_query)(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query);
+ unlang_function_t sql_query;
+ unlang_function_t sql_select_query;
sql_rcode_t (*sql_store_result)(rlm_sql_handle_t *handle, rlm_sql_config_t const *config);
int (*sql_num_fields)(rlm_sql_handle_t *handle, rlm_sql_config_t const *config);
for (i = 0; i < (count + 1); i++) {
ROPTIONAL(RDEBUG2, DEBUG2, "Executing query: %s", query_ctx->query_str);
- query_ctx->rcode = (inst->driver->sql_query)(query_ctx->handle, &inst->config, query_ctx->query_str);
+ (inst->driver->sql_query)(p_result, NULL, request, query_ctx);
query_ctx->status = SQL_QUERY_SUBMITTED;
switch (query_ctx->rcode) {
case RLM_SQL_OK:
for (i = 0; i < (count + 1); i++) {
ROPTIONAL(RDEBUG2, DEBUG2, "Executing select query: %s", query_ctx->query_str);
- query_ctx->rcode = (inst->driver->sql_select_query)(query_ctx->handle, &inst->config, query_ctx->query_str);
+ (inst->driver->sql_select_query)(p_result, NULL, request, query_ctx);
query_ctx->status = SQL_QUERY_SUBMITTED;
switch (query_ctx->rcode) {
case RLM_SQL_OK: