From: Nick Porter Date: Fri, 26 Apr 2024 15:01:33 +0000 (+0100) Subject: Define an SQL query context X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=37f2811757ff6c0a763576efcdef43041e206650;p=thirdparty%2Ffreeradius-server.git Define an SQL query context And allocation / free routines --- diff --git a/src/modules/rlm_sql/rlm_sql.c b/src/modules/rlm_sql/rlm_sql.c index 6f3007ef786..a545f054c5b 100644 --- a/src/modules/rlm_sql/rlm_sql.c +++ b/src/modules/rlm_sql/rlm_sql.c @@ -1831,6 +1831,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) inst->query = rlm_sql_query; inst->select = rlm_sql_select_query; inst->fetch_row = rlm_sql_fetch_row; + inst->query_alloc = fr_sql_query_alloc; /* * Either use the module specific escape function diff --git a/src/modules/rlm_sql/rlm_sql.h b/src/modules/rlm_sql/rlm_sql.h index fa41f336e7a..a34c361984e 100644 --- a/src/modules/rlm_sql/rlm_sql.h +++ b/src/modules/rlm_sql/rlm_sql.h @@ -105,6 +105,29 @@ typedef struct { //!< when log strings need to be copied. } rlm_sql_handle_t; +typedef enum { + SQL_QUERY_SELECT, + SQL_QUERY_OTHER +} fr_sql_query_type_t; + +/** Status of an SQL query + */ +typedef enum { + SQL_QUERY_FAILED = -1, //!< Failed to submit. + SQL_QUERY_PREPARED = 0, //!< Ready to submit. + SQL_QUERY_SUBMITTED, //!< Submitted for execution. + SQL_QUERY_RESULTS_FETCHED //!< Results fetched from the server. +} fr_sql_query_status_t; + +typedef struct { + rlm_sql_t const *inst; //!< Module instance for this query. + rlm_sql_handle_t *handle; //!< Connection handle this query is being run on. + char const *query_str; //!< Query string to run. + fr_sql_query_type_t type; //!< Type of query. + fr_sql_query_status_t status; //!< Status of the query. + sql_rcode_t rcode; //!< Result code. +} fr_sql_query_t; + extern fr_table_num_sorted_t const sql_rcode_description_table[]; extern size_t sql_rcode_description_table_len; extern fr_table_num_sorted_t const sql_rcode_table[]; @@ -188,6 +211,7 @@ struct sql_inst { sql_rcode_t (*query)(rlm_sql_t const *inst, request_t *request, rlm_sql_handle_t **handle, char const *query); sql_rcode_t (*select)(rlm_sql_t const *inst, request_t *request, rlm_sql_handle_t **handle, char const *query); sql_rcode_t (*fetch_row)(rlm_sql_row_t *out, rlm_sql_t const *inst, request_t *request, rlm_sql_handle_t **handle); + fr_sql_query_t *(*query_alloc)(TALLOC_CTX *ctx, rlm_sql_t const *inst, rlm_sql_handle_t *handle, char const *query_str, fr_sql_query_type_t type); char const *name; //!< Module instance name. fr_dict_attr_t const *group_da; //!< Group dictionary attribute. @@ -200,6 +224,7 @@ sql_rcode_t rlm_sql_select_query(rlm_sql_t const *inst, request_t *request, rlm_ sql_rcode_t rlm_sql_query(rlm_sql_t const *inst, request_t *request, rlm_sql_handle_t **handle, char const *query) CC_HINT(nonnull (1, 3, 4)); sql_rcode_t rlm_sql_fetch_row(rlm_sql_row_t *out, rlm_sql_t const *inst, request_t *request, rlm_sql_handle_t **handle); void rlm_sql_print_error(rlm_sql_t const *inst, request_t *request, rlm_sql_handle_t *handle, bool force_debug); +fr_sql_query_t *fr_sql_query_alloc(TALLOC_CTX *ctx, rlm_sql_t const *inst, rlm_sql_handle_t *handle, char const *query_str, fr_sql_query_type_t type); /* * sql_state.c diff --git a/src/modules/rlm_sql/sql.c b/src/modules/rlm_sql/sql.c index c31ea652034..a0af6d73280 100644 --- a/src/modules/rlm_sql/sql.c +++ b/src/modules/rlm_sql/sql.c @@ -373,6 +373,38 @@ void rlm_sql_print_error(rlm_sql_t const *inst, request_t *request, rlm_sql_hand talloc_free_children(handle->log_ctx); } +/** Automatically run the correct `finish` function when freeing an SQL query + * + */ +static int fr_sql_query_free(fr_sql_query_t *to_free) +{ + if (to_free->status <= 0) return 0; + if (to_free->type == SQL_QUERY_SELECT) { + (to_free->inst->driver->sql_finish_select_query)(to_free->handle, &to_free->inst->config); + } else { + (to_free->inst->driver->sql_finish_query)(to_free->handle, &to_free->inst->config); + } + return 0; +} + +/** Allocate an sql query structure + * + */ +fr_sql_query_t *fr_sql_query_alloc(TALLOC_CTX *ctx, rlm_sql_t const *inst, rlm_sql_handle_t *handle, + char const *query_str, fr_sql_query_type_t type) +{ + fr_sql_query_t *query; + MEM(query = talloc(ctx, fr_sql_query_t)); + *query = (fr_sql_query_t) { + .inst = inst, + .handle = handle, + .query_str = query_str, + .type = type + }; + talloc_set_destructor(query, fr_sql_query_free); + return query; +} + /** Call the driver's sql_query method, reconnecting if necessary. * * @note Caller must call ``(inst->driver->sql_finish_query)(handle, &inst->config);``