You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
proxysql/include/PgSQL_Extended_Query_Message.h

187 lines
6.1 KiB

#ifndef CLASS_PGSQL_EXTENDED_QUERY_MESSAGE_H
#define CLASS_PGSQL_EXTENDED_QUERY_MESSAGE_H
#include "proxysql.h"
#include "cpp.h"
template<typename DATA, typename DERIVED>
class Base_Extended_Query_Message {
public:
Base_Extended_Query_Message();
~Base_Extended_Query_Message();
/**
* @brief Releases the ownership of the packet and returns a new message object.
*
* This method transfers ownership of the packet data to a new message object
* and resets the current message's internal state.
*
* @return A pointer to the newly created message object with transferred data.
*/
DERIVED* release();
/**
* @brief Parses the packet data and populates the message data.
*
* This method should be implemented by derived classes to parse the packet
* and fill the `_data` member with relevant information.
*
* @param pkt The packet data to parse.
* @return True if parsing was successful, false otherwise.
*/
PtrSize_t detach();
inline const DATA* data() const {
return &_data;
}
protected:
DATA _data {};
PtrSize_t _pkt = {};
};
struct PgSQL_Parse_Data {
const char* stmt_name; // The name of the prepared statement
const char* query_string; // The query string to be prepared
uint16_t num_param_types; // Number of parameter types specified
const uint32_t* param_types; // Array of parameter types (can be nullptr if none)
};
class PgSQL_Parse_Message : public Base_Extended_Query_Message<PgSQL_Parse_Data,PgSQL_Parse_Message> {
public:
/**
* @brief Parses the PgSQL_Parse_Message from the provided packet.
*
* This method extracts the statement name, query string, parameter types,
* and initializes the internal state of the PgSQL_Parse_Message object.
*
* @param pkt The packet containing the PgSQL_Parse_Message data.
*
* @return True if parsing was successful, false otherwise.
*/
bool parse(PtrSize_t& pkt);
};
struct PgSQL_Describe_Data {
const char* stmt_name; // The name of the prepared statement or portal
uint8_t stmt_type; // 'S' for statement, 'P' for portal
};
class PgSQL_Describe_Message : public Base_Extended_Query_Message<PgSQL_Describe_Data, PgSQL_Describe_Message> {
public:
/**
* @brief Parses the PgSQL_Describe_Message from the provided packet.
*
* This method extracts the statement type and name from the packet and
* initializes the internal state of the PgSQL_Describe_Message object.
*
* @param pkt The packet containing the PgSQL_Describe_Message data.
*
* @return True if parsing was successful, false otherwise.
*/
bool parse(PtrSize_t& pkt);
};
struct PgSQL_Close_Data {
uint8_t stmt_type; // 'S' for statement, 'P' for portal
const char* stmt_name; // The name of the prepared statement or portal
};
//create close statement message
class PgSQL_Close_Message : public Base_Extended_Query_Message<PgSQL_Close_Data,PgSQL_Close_Message> {
public:
/**
* @brief Parses the PgSQL_Close_Message from the provided packet.
*
* This method extracts the statement type and name from the packet and
* initializes the internal state of the PgSQL_Close_Message object.
*
* @param pkt The packet containing the PgSQL_Close_Message data.
*
* @return True if parsing was successful, false otherwise.
*/
bool parse(PtrSize_t& pkt);
};
struct PgSQL_Bind_Data {
const char* portal_name; // The name of the portal to bind
const char* stmt_name; // The name of the prepared statement to bind
uint16_t num_param_formats; // Number of parameter formats
uint16_t num_param_values; // Number of parameter values
uint16_t num_result_formats; // Number of result format codes
private:
const uint16_t* param_formats; // Array of parameter types (can be nullptr if none)
const uint8_t* param_values; // Array of parameter values (can be nullptr if none)
const uint16_t* result_formats; // Array of result format codes (can be nullptr if none)
friend class PgSQL_Bind_Message;
};
class PgSQL_Bind_Message : public Base_Extended_Query_Message<PgSQL_Bind_Data,PgSQL_Bind_Message> {
public:
typedef struct {
int32_t len; // Length of value (-1 for NULL)
const unsigned char* value; // Pointer to value data
} ParamValue_t;
// Iterator context for parameter values
typedef struct {
const unsigned char* current; // Current position in values
uint16_t remaining; // Parameters remaining
} ParamValueIterCtx;
// Iterator context for format arrays
typedef struct {
const unsigned char* current; // Current position in array
uint16_t remaining; // Formats remaining
} FormatIterCtx;
/**
* @brief Parses the PgSQL_Bind_Message from the provided packet.
*
* This method extracts the portal name, statement name, parameter formats,
* parameter values, and result formats from the packet and initializes the
* internal state of the PgSQL_Bind_Message object.
*
* @param pkt The packet containing the PgSQL_Bind_Message data.
*
* @return True if parsing was successful, false otherwise.
*/
bool parse(PtrSize_t& pkt);
// Initialize param format iterator
void init_param_format_iter(FormatIterCtx* ctx) const;
// Initialize parameter value iterator
void init_param_value_iter(ParamValueIterCtx* ctx) const;
// Get next parameter value
bool next_param_value(ParamValueIterCtx* ctx, ParamValue_t* out) const;
// Initialize result format iterator
void init_result_format_iter(FormatIterCtx* ctx) const;
// Get next format value
bool next_format(FormatIterCtx* ctx, uint16_t* out) const;
};
struct PgSQL_Execute_Data {
const char* portal_name; // The name of the portal to execute
uint32_t max_rows; // Maximum number of rows to return (0 for no limit)
};
class PgSQL_Execute_Message : public Base_Extended_Query_Message<PgSQL_Execute_Data,PgSQL_Execute_Message> {
public:
/**
* @brief Parses the PgSQL_Execute_Message from the provided packet.
*
* This method extracts the portal name and maximum rows from the packet
* and initializes the internal state of the PgSQL_Execute_Message object.
*
* @param pkt The packet containing the PgSQL_Execute_Message data.
*
* @return True if parsing was successful, false otherwise.
*/
bool parse(PtrSize_t& pkt);
};
#endif /* CLASS_PGSQL_EXTENDED_QUERY_MESSAGE_H */