diff --git a/include/mysql/impl/messages.hpp b/include/mysql/impl/messages.hpp index 02e58a3c..2d18f339 100644 --- a/include/mysql/impl/messages.hpp +++ b/include/mysql/impl/messages.hpp @@ -189,7 +189,7 @@ struct get_struct_fields ); }; -// Commands +// Commands (text protocol) struct com_query_packet { string_eof query; @@ -205,6 +205,44 @@ struct get_struct_fields ); }; +// Commands (prepared statements) +struct com_stmt_prepare_packet +{ + string_eof statement; + + static constexpr std::uint8_t command_id = 0x16; +}; + +template <> +struct get_struct_fields +{ + static constexpr auto value = std::make_tuple( + &com_stmt_prepare_packet::statement + ); +}; + +struct com_stmt_prepare_ok_packet +{ + // int1 status: must be 0 + int4 statement_id; + int2 num_columns; + int2 num_params; + // int1 reserved_1: must be 0 + int2 warning_count; + // TODO: int1 metadata_follows when CLIENT_OPTIONAL_RESULTSET_METADATA +}; + +template <> +struct get_struct_fields +{ + static constexpr auto value = std::make_tuple( + &com_stmt_prepare_ok_packet::statement_id, + &com_stmt_prepare_ok_packet::num_columns, + &com_stmt_prepare_ok_packet::num_params, + &com_stmt_prepare_ok_packet::warning_count + ); +}; + // serialization functions inline Error deserialize(ok_packet& output, DeserializationContext& ctx) noexcept; @@ -213,6 +251,7 @@ inline std::size_t get_size(const handshake_response_packet& value, const Serial inline void serialize(const handshake_response_packet& value, SerializationContext& ctx) noexcept; inline Error deserialize(auth_switch_request_packet& output, DeserializationContext& ctx) noexcept; inline Error deserialize(column_definition_packet& output, DeserializationContext& ctx) noexcept; +inline Error deserialize(com_stmt_prepare_ok_packet& output, DeserializationContext& ctx) noexcept; // Helper to serialize top-level messages template @@ -235,21 +274,7 @@ inline std::pair deserialize_message_type( inline error_code process_error_packet(DeserializationContext& ctx, error_info& info); -/*struct StmtPrepare -{ - string_eof statement; -}; - -struct StmtPrepareResponseHeader -{ - // int1 status: must be 0 - int4 statement_id; - int2 num_columns; - int2 num_params; - // int1 reserved_1: must be 0 - int2 warning_count; // only if (packet_length > 12) - // TODO: int1 metadata_follows when CLIENT_OPTIONAL_RESULTSET_METADATA -}; +/* using BinaryValue = std::variant< std::int8_t, diff --git a/include/mysql/impl/messages.ipp b/include/mysql/impl/messages.ipp index eb2b659f..f7bb0714 100644 --- a/include/mysql/impl/messages.ipp +++ b/include/mysql/impl/messages.ipp @@ -167,6 +167,22 @@ inline mysql::Error mysql::detail::deserialize( ); } +inline mysql::Error mysql::detail::deserialize( + com_stmt_prepare_ok_packet& output, + DeserializationContext& ctx +) noexcept +{ + int1 reserved; + return deserialize_fields( + ctx, + output.statement_id, + output.num_columns, + output.num_params, + reserved, + output.warning_count + ); +} + template void mysql::detail::serialize_message( const Serializable& input, diff --git a/test/unit/serialization.cpp b/test/unit/serialization.cpp index f921117b..5311a295 100644 --- a/test/unit/serialization.cpp +++ b/test/unit/serialization.cpp @@ -493,5 +493,30 @@ INSTANTIATE_TEST_SUITE_P(ComQuery, SerializeTest, testing::Values( }) )); +INSTANTIATE_TEST_SUITE_P(ComStmtPrepare, SerializeTest, testing::Values( + SerializeParams(com_stmt_prepare_packet{ + string_eof("SELECT * from three_rows_table WHERE id = ?") + }, { + 0x16, 0x53, 0x45, 0x4c, 0x45, 0x43, 0x54, 0x20, + 0x2a, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, + 0x68, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x6f, 0x77, + 0x73, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x57, 0x48, 0x45, 0x52, 0x45, 0x20, 0x69, 0x64, + 0x20, 0x3d, 0x20, 0x3f + }) +)); + +INSTANTIATE_TEST_SUITE_P(ComStmtPrepareResponse, DeserializeSpaceTest, testing::Values( + SerializeParams(com_stmt_prepare_ok_packet{ + int4(1), // statement id + int2(2), // number of fields + int2(3), // number of params + int2(0), // warnings + }, { + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00 + }) +)); + } // anon namespace