]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Define an SQL query context
authorNick Porter <nick@portercomputing.co.uk>
Fri, 26 Apr 2024 15:01:33 +0000 (16:01 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 7 Jun 2024 02:26:58 +0000 (22:26 -0400)
And allocation / free routines

src/modules/rlm_sql/rlm_sql.c
src/modules/rlm_sql/rlm_sql.h
src/modules/rlm_sql/sql.c

index 6f3007ef786f53f44dcbf76300e5585105546002..a545f054c5b2e36840b874f79b4e44e0ef66c47f 100644 (file)
@@ -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
index fa41f336e7aebc4655ba6f5d27606ce568298d43..a34c361984e2c524f102a41c1036c143c94cd897 100644 (file)
@@ -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
index c31ea652034c7c5d82b1bd9c6cb5597d63bd6a76..a0af6d732805cba996f836de5d8e66826806b9cd 100644 (file)
@@ -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);``