char **results; //!< Result strings from statement execution.
char *error; //!< The last error string created by one of the call backs.
bool established; //!< Set to false once the connection has been properly established.
+ CS_INT rows_affected; //!< Rows affected by last INSERT / UPDATE / DELETE.
} rlm_sql_freetds_conn_t;
#define MAX_DATASTR_LEN 256
CS_RETCODE results_ret;
CS_INT result_type;
+ /*
+ * Reset rows_affected in case the query fails.
+ * Prevents accidentally returning the rows_affected from a previous query.
+ */
+ conn->rows_affected = -1;
+
if (ct_cmd_alloc(conn->db, &conn->command) != CS_SUCCEED) {
ERROR("Unable to allocate command structure (ct_cmd_alloc())");
}
}
+ /*
+ * Retrieve the number of rows affected - the later calls
+ * to ct_results end up resetting the underlying counter so we
+ * no longer have access to this.
+ */
+ 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;
+ }
+
/*
* Second call to ct_results, we need returncode CS_SUCCEED
* and result_type CS_CMD_DONE.
static int sql_num_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
{
rlm_sql_freetds_conn_t *conn = handle->conn;
- int num;
- if (ct_res_info(conn->command, CS_ROW_COUNT, (CS_INT *)&num, CS_UNUSED, NULL) != CS_SUCCEED) {
- ERROR("error retrieving row count");
-
- return RLM_SQL_ERROR;
- }
-
- return num;
+ return (conn->rows_affected);
}
static sql_rcode_t sql_fetch_row(rlm_sql_row_t *out, rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
return RLM_SQL_ERROR;
}
conn->command = NULL;
+ conn->rows_affected = -1;
return RLM_SQL_OK;
}