mirror of
https://github.com/boostorg/mysql.git
synced 2026-02-15 01:02:17 +00:00
Prepared statement methods
This commit is contained in:
@@ -521,7 +521,7 @@ public:
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
template<
|
||||
class ValueCollection,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
|
||||
@@ -30,8 +30,8 @@ async_connect(
|
||||
channel<Stream>& chan,
|
||||
const typename Stream::lowest_layer_type::endpoint_type& endpoint,
|
||||
const connection_params& params,
|
||||
CompletionToken&& token,
|
||||
error_info& info
|
||||
error_info& info,
|
||||
CompletionToken&& token
|
||||
);
|
||||
|
||||
} // detail
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <boost/mysql/detail/network_algorithms/common.hpp>
|
||||
#include <boost/mysql/resultset.hpp>
|
||||
#include <boost/mysql/value.hpp>
|
||||
#include <boost/mysql/prepared_statement.hpp>
|
||||
#include <boost/mysql/execute_params.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -19,9 +21,7 @@ namespace detail {
|
||||
template <class Stream, class ValueForwardIterator>
|
||||
void execute_statement(
|
||||
channel<Stream>& channel,
|
||||
std::uint32_t statement_id,
|
||||
ValueForwardIterator params_begin,
|
||||
ValueForwardIterator params_end,
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
resultset& output,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
@@ -31,9 +31,7 @@ template <class Stream, class ValueForwardIterator, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_execute_statement(
|
||||
channel<Stream>& chan,
|
||||
std::uint32_t statement_id,
|
||||
ValueForwardIterator params_begin,
|
||||
ValueForwardIterator params_end,
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
resultset& output,
|
||||
error_info& info,
|
||||
CompletionToken&& token
|
||||
|
||||
@@ -32,8 +32,8 @@ BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_handshake(
|
||||
channel<Stream>& channel,
|
||||
const connection_params& params,
|
||||
CompletionToken&& token,
|
||||
error_info& info
|
||||
error_info& info,
|
||||
CompletionToken&& token
|
||||
);
|
||||
|
||||
} // detail
|
||||
|
||||
@@ -110,8 +110,8 @@ boost::mysql::detail::async_connect(
|
||||
channel<Stream>& chan,
|
||||
const typename Stream::lowest_layer_type::endpoint_type& endpoint,
|
||||
const connection_params& params,
|
||||
CompletionToken&& token,
|
||||
error_info& info
|
||||
error_info& info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code)>(
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/resultset.hpp>
|
||||
#include <boost/mysql/execute_params.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/execute_statement.hpp>
|
||||
#include <boost/mysql/detail/protocol/binary_deserialization.hpp>
|
||||
#include <boost/mysql/detail/protocol/prepared_statement_messages.hpp>
|
||||
@@ -22,21 +23,20 @@ namespace detail {
|
||||
|
||||
template <class ValueForwardIterator>
|
||||
com_stmt_execute_packet<ValueForwardIterator> make_stmt_execute_packet(
|
||||
std::uint32_t statement_id,
|
||||
ValueForwardIterator params_begin,
|
||||
ValueForwardIterator params_end
|
||||
const execute_params<ValueForwardIterator>& params
|
||||
)
|
||||
{
|
||||
return com_stmt_execute_packet<ValueForwardIterator> {
|
||||
statement_id,
|
||||
params.statement_id(),
|
||||
std::uint8_t(0), // flags
|
||||
std::uint32_t(1), // iteration count
|
||||
std::uint8_t(1), // new params flag: set
|
||||
params_begin,
|
||||
params_end
|
||||
params.first(),
|
||||
params.last()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
@@ -44,9 +44,7 @@ com_stmt_execute_packet<ValueForwardIterator> make_stmt_execute_packet(
|
||||
template <class Stream, class ValueForwardIterator>
|
||||
void boost::mysql::detail::execute_statement(
|
||||
channel<Stream>& chan,
|
||||
std::uint32_t statement_id,
|
||||
ValueForwardIterator params_begin,
|
||||
ValueForwardIterator params_end,
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
resultset& output,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
@@ -55,7 +53,7 @@ void boost::mysql::detail::execute_statement(
|
||||
execute_generic(
|
||||
&deserialize_binary_row,
|
||||
chan,
|
||||
make_stmt_execute_packet(statement_id, params_begin, params_end),
|
||||
make_stmt_execute_packet(params),
|
||||
output,
|
||||
err,
|
||||
info
|
||||
@@ -69,9 +67,7 @@ BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
)
|
||||
boost::mysql::detail::async_execute_statement(
|
||||
channel<Stream>& chan,
|
||||
std::uint32_t statement_id,
|
||||
ValueForwardIterator params_begin,
|
||||
ValueForwardIterator params_end,
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
resultset& output,
|
||||
error_info& info,
|
||||
CompletionToken&& token
|
||||
@@ -80,7 +76,7 @@ boost::mysql::detail::async_execute_statement(
|
||||
return async_execute_generic(
|
||||
&deserialize_binary_row,
|
||||
chan,
|
||||
make_stmt_execute_packet(statement_id, params_begin, params_end),
|
||||
make_stmt_execute_packet(params),
|
||||
output,
|
||||
info,
|
||||
std::forward<CompletionToken>(token)
|
||||
|
||||
@@ -551,8 +551,8 @@ BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
boost::mysql::detail::async_handshake(
|
||||
channel<Stream>& chan,
|
||||
const connection_params& params,
|
||||
CompletionToken&& token,
|
||||
error_info& info
|
||||
error_info& info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
chan.reset();
|
||||
|
||||
@@ -10,13 +10,35 @@
|
||||
|
||||
#include <boost/mysql/value.hpp>
|
||||
#include <boost/mysql/prepared_statement.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/stringize.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/value_type_traits.hpp>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
|
||||
// TODO: move this to impl file
|
||||
namespace detail {
|
||||
|
||||
template <class ValueForwardIterator>
|
||||
void check_num_params(
|
||||
ValueForwardIterator first,
|
||||
ValueForwardIterator last,
|
||||
const prepared_statement& stmt
|
||||
)
|
||||
{
|
||||
auto param_count = std::distance(first, last);
|
||||
if (param_count != stmt.num_params())
|
||||
{
|
||||
throw std::domain_error(detail::stringize(
|
||||
"prepared_statement::execute: expected ", stmt.num_params(), " params, but got ", param_count));
|
||||
}
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
|
||||
/**
|
||||
* \brief Represents the parameters required to execute a [reflink prepared_statement].
|
||||
@@ -41,53 +63,27 @@ class execute_params
|
||||
"ValueForwardIterator requirements not met");
|
||||
public:
|
||||
/// Constructor.
|
||||
constexpr execute_params(
|
||||
std::uint32_t statement_id,
|
||||
execute_params(
|
||||
const prepared_statement& stmt,
|
||||
ValueForwardIterator first,
|
||||
ValueForwardIterator last
|
||||
) :
|
||||
statement_id_(statement_id),
|
||||
statement_id_(stmt.id()),
|
||||
first_(first),
|
||||
last_(last)
|
||||
{
|
||||
detail::check_num_params(first, last, stmt);
|
||||
}
|
||||
|
||||
constexpr std::uint32_t statement_id() const noexcept { return statement_id_; }
|
||||
|
||||
void set_statement_id(std::uint32_t v) noexcept { statement_id_ = v; }
|
||||
|
||||
/// Retrieves the parameter value range's begin.
|
||||
constexpr ValueForwardIterator first() const { return first_; }
|
||||
|
||||
/// Retrieves the parameter value range's end.
|
||||
constexpr ValueForwardIterator last() const { return last_; }
|
||||
|
||||
/// Sets the parameter value range's begin.
|
||||
void set_first(ValueForwardIterator v) { first_ = v;}
|
||||
|
||||
/// Sets the parameter value range's end.
|
||||
void set_last(ValueForwardIterator v) { last_ = v; }
|
||||
};
|
||||
|
||||
/**
|
||||
* \relates execute_params
|
||||
* \brief Creates an instance of [reflink execute_params] from a pair of iterators.
|
||||
* \details ValueForwardIterator should meet the [reflink ValueForwardIterator] type requirements.
|
||||
*/
|
||||
template <
|
||||
class ValueForwardIterator,
|
||||
class EnableIf = detail::enable_if_value_forward_iterator<ValueForwardIterator>
|
||||
>
|
||||
constexpr execute_params<ValueForwardIterator>
|
||||
make_execute_params(
|
||||
std::uint32_t statement_id,
|
||||
ValueForwardIterator first,
|
||||
ValueForwardIterator last
|
||||
)
|
||||
{
|
||||
return execute_params<ValueForwardIterator>(statement_id, first, last);
|
||||
}
|
||||
|
||||
template <
|
||||
class ValueForwardIterator,
|
||||
class EnableIf = detail::enable_if_value_forward_iterator<ValueForwardIterator>
|
||||
@@ -99,23 +95,7 @@ make_execute_params(
|
||||
ValueForwardIterator last
|
||||
)
|
||||
{
|
||||
return execute_params<ValueForwardIterator>(stmt.id(), first, last);
|
||||
}
|
||||
|
||||
/**
|
||||
* \relates execute_params
|
||||
* \brief Creates an instance of [reflink execute_params] from a collection.
|
||||
* \details ValueCollection should meet the [reflink ValueCollection] type requirements.
|
||||
*/
|
||||
template <
|
||||
class ValueCollection,
|
||||
class EnableIf = detail::enable_if_value_collection<ValueCollection>
|
||||
>
|
||||
constexpr auto make_execute_params(
|
||||
const ValueCollection& col
|
||||
) -> execute_params<decltype(std::begin(col))>
|
||||
{
|
||||
return make_execute_params(std::begin(col), std::end(col));
|
||||
return execute_params<ValueForwardIterator>(stmt, first, last);
|
||||
}
|
||||
|
||||
template <
|
||||
@@ -127,7 +107,7 @@ constexpr auto make_execute_params(
|
||||
const ValueCollection& col
|
||||
) -> execute_params<decltype(std::begin(col))>
|
||||
{
|
||||
return make_execute_params(stmt.id(), std::begin(col), std::end(col));
|
||||
return make_execute_params(stmt, std::begin(col), std::end(col));
|
||||
}
|
||||
|
||||
} // mysql
|
||||
|
||||
@@ -11,15 +11,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/connection.hpp>
|
||||
#include <boost/mysql/prepared_statement.hpp>
|
||||
#include <boost/mysql/resultset.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/connect.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/handshake.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/execute_query.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/prepare_statement.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/execute_statement.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/close_statement.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/read_one_row.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/quit_connection.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/close_connection.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <utility>
|
||||
|
||||
|
||||
// connect
|
||||
template <class Stream>
|
||||
template <class EndpointType>
|
||||
void boost::mysql::connection<Stream>::connect(
|
||||
@@ -66,11 +73,13 @@ boost::mysql::connection<Stream>::async_connect(
|
||||
this->get_channel(),
|
||||
endpoint,
|
||||
params,
|
||||
std::forward<CompletionToken>(token),
|
||||
output_info
|
||||
output_info,
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// handshake
|
||||
template <class Stream>
|
||||
void boost::mysql::connection<Stream>::handshake(
|
||||
const connection_params& params,
|
||||
@@ -108,47 +117,46 @@ boost::mysql::connection<Stream>::async_handshake(
|
||||
return detail::async_handshake(
|
||||
get_channel(),
|
||||
params,
|
||||
std::forward<CompletionToken>(token),
|
||||
output_info
|
||||
output_info,
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
// Query
|
||||
template <class Stream>
|
||||
boost::mysql::resultset<Stream> boost::mysql::connection<Stream>::query(
|
||||
void boost::mysql::connection<Stream>::query(
|
||||
boost::string_view query_string,
|
||||
resultset& result,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
detail::clear_errors(err, info);
|
||||
resultset<Stream> res;
|
||||
detail::execute_query(get_channel(), query_string, res, err, info);
|
||||
return res;
|
||||
detail::execute_query(get_channel(), query_string, result, err, info);
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
boost::mysql::resultset<Stream> boost::mysql::connection<Stream>::query(
|
||||
boost::string_view query_string
|
||||
void boost::mysql::connection<Stream>::query(
|
||||
boost::string_view query_string,
|
||||
resultset& result
|
||||
)
|
||||
{
|
||||
resultset<Stream> res;
|
||||
detail::error_block blk;
|
||||
detail::execute_query(get_channel(), query_string, res, blk.err, blk.info);
|
||||
detail::execute_query(get_channel(), query_string, result, blk.err, blk.info);
|
||||
blk.check();
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::resultset<Stream>)
|
||||
void(::boost::mysql::error_code)
|
||||
) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code, boost::mysql::resultset<Stream>)
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
boost::mysql::connection<Stream>::async_query(
|
||||
boost::string_view query_string,
|
||||
resultset& result,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
@@ -157,46 +165,48 @@ boost::mysql::connection<Stream>::async_query(
|
||||
return detail::async_execute_query(
|
||||
get_channel(),
|
||||
query_string,
|
||||
std::forward<CompletionToken>(token),
|
||||
output_info
|
||||
result,
|
||||
output_info,
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Prepare statement
|
||||
template <class Stream>
|
||||
boost::mysql::prepared_statement<Stream> boost::mysql::connection<Stream>::prepare_statement(
|
||||
void boost::mysql::connection<Stream>::prepare_statement(
|
||||
boost::string_view statement,
|
||||
prepared_statement& output,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
mysql::prepared_statement<Stream> res;
|
||||
detail::clear_errors(err, info);
|
||||
detail::prepare_statement(get_channel(), statement, err, info, res);
|
||||
return res;
|
||||
detail::prepare_statement(get_channel(), statement, output, err, info);
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
boost::mysql::prepared_statement<Stream> boost::mysql::connection<Stream>::prepare_statement(
|
||||
boost::string_view statement
|
||||
void boost::mysql::connection<Stream>::prepare_statement(
|
||||
boost::string_view statement,
|
||||
prepared_statement& output
|
||||
)
|
||||
{
|
||||
mysql::prepared_statement<Stream> res;
|
||||
detail::error_block blk;
|
||||
detail::prepare_statement(get_channel(), statement, blk.err, blk.info, res);
|
||||
detail::prepare_statement(get_channel(), statement, output, blk.err, blk.info);
|
||||
blk.check();
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::prepared_statement<Stream>)
|
||||
void(::boost::mysql::error_code)
|
||||
) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code, boost::mysql::prepared_statement<Stream>)
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
boost::mysql::connection<Stream>::async_prepare_statement(
|
||||
boost::string_view statement,
|
||||
prepared_statement& output,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
@@ -205,12 +215,125 @@ boost::mysql::connection<Stream>::async_prepare_statement(
|
||||
return detail::async_prepare_statement(
|
||||
get_channel(),
|
||||
statement,
|
||||
output,
|
||||
output_info,
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Execute statement
|
||||
template <class Stream>
|
||||
template <class ValueForwardIterator>
|
||||
void boost::mysql::connection<Stream>::execute_statement(
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
resultset& result,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
detail::clear_errors(err, info);
|
||||
detail::execute_statement(
|
||||
get_channel(),
|
||||
params,
|
||||
result,
|
||||
err,
|
||||
info
|
||||
);
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
template <class ValueForwardIterator>
|
||||
void boost::mysql::connection<Stream>::execute_statement(
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
resultset& result
|
||||
)
|
||||
{
|
||||
detail::error_block blk;
|
||||
detail::execute_statement(
|
||||
get_channel(),
|
||||
params,
|
||||
result,
|
||||
blk.err,
|
||||
blk.info
|
||||
);
|
||||
blk.check();
|
||||
}
|
||||
|
||||
|
||||
template <class Stream>
|
||||
template <class ValueForwardIterator, BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code)
|
||||
) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
boost::mysql::connection<Stream>::async_execute_statement(
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
resultset& result,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
output_info.clear();
|
||||
detail::async_execute_statement(
|
||||
get_channel(),
|
||||
params,
|
||||
result,
|
||||
output_info,
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
// Close statement
|
||||
template <class Stream>
|
||||
void boost::mysql::connection<Stream>::close_statement(
|
||||
const prepared_statement& stmt,
|
||||
error_code& code,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
detail::clear_errors(code, info);
|
||||
detail::close_statement(get_channel(), stmt.id(), code, info);
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::connection<Stream>::close_statement(
|
||||
const prepared_statement& stmt
|
||||
)
|
||||
{
|
||||
detail::error_block blk;
|
||||
detail::close_statement(get_channel(), stmt.id(), blk.err, blk.info);
|
||||
blk.check();
|
||||
}
|
||||
|
||||
|
||||
template <class Stream>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code)
|
||||
) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
boost::mysql::connection<Stream>::async_close_statement(
|
||||
const prepared_statement& stmt,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
output_info.clear();
|
||||
return detail::async_close_statement(
|
||||
get_channel(),
|
||||
stmt.id(),
|
||||
std::forward<CompletionToken>(token),
|
||||
output_info
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Close
|
||||
template <class Stream>
|
||||
void boost::mysql::connection<Stream>::close(
|
||||
error_code& err,
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2019-2022 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_MYSQL_IMPL_PREPARED_STATEMENT_HPP
|
||||
#define BOOST_MYSQL_IMPL_PREPARED_STATEMENT_HPP
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/prepared_statement.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/execute_statement.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/close_statement.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/stringize.hpp>
|
||||
#include <boost/asio/bind_executor.hpp>
|
||||
|
||||
|
||||
template <class Stream>
|
||||
template <class ValueForwardIterator>
|
||||
void boost::mysql::prepared_statement<Stream>::check_num_params(
|
||||
ValueForwardIterator first,
|
||||
ValueForwardIterator last,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
) const
|
||||
{
|
||||
auto param_count = std::distance(first, last);
|
||||
if (param_count != num_params())
|
||||
{
|
||||
err = make_error_code(errc::wrong_num_params);
|
||||
info.set_message(detail::stringize(
|
||||
"prepared_statement::execute: expected ", num_params(), " params, but got ", param_count));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Stream>
|
||||
template <class ValueForwardIterator>
|
||||
boost::mysql::resultset<Stream> boost::mysql::prepared_statement<Stream>::execute(
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
assert(valid());
|
||||
|
||||
mysql::resultset<Stream> res;
|
||||
detail::clear_errors(err, info);
|
||||
|
||||
// Verify we got passed the right number of params
|
||||
check_num_params(params.first(), params.last(), err, info);
|
||||
if (!err)
|
||||
{
|
||||
detail::execute_statement(
|
||||
*channel_,
|
||||
stmt_msg_.statement_id,
|
||||
params.first(),
|
||||
params.last(),
|
||||
res,
|
||||
err,
|
||||
info
|
||||
);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
template <class ValueForwardIterator>
|
||||
boost::mysql::resultset<Stream> boost::mysql::prepared_statement<Stream>::execute(
|
||||
const execute_params<ValueForwardIterator>& params
|
||||
)
|
||||
{
|
||||
detail::error_block blk;
|
||||
auto res = execute(params, blk.err, blk.info);
|
||||
blk.check();
|
||||
return res;
|
||||
}
|
||||
|
||||
// Helper for async_execute
|
||||
template <class Stream>
|
||||
struct boost::mysql::prepared_statement<Stream>::async_execute_initiation
|
||||
{
|
||||
template <class HandlerType>
|
||||
struct error_handler
|
||||
{
|
||||
error_code err;
|
||||
HandlerType h;
|
||||
|
||||
void operator()()
|
||||
{
|
||||
std::forward<HandlerType>(h)(err, resultset<Stream>());
|
||||
}
|
||||
};
|
||||
|
||||
template <class HandlerType, class ValueForwardIterator>
|
||||
void operator()(
|
||||
HandlerType&& handler,
|
||||
error_code err,
|
||||
error_info& info,
|
||||
prepared_statement<Stream>& stmt,
|
||||
ValueForwardIterator params_first,
|
||||
ValueForwardIterator params_last
|
||||
) const
|
||||
{
|
||||
if (err)
|
||||
{
|
||||
auto executor = boost::asio::get_associated_executor(
|
||||
handler,
|
||||
stmt.next_layer().get_executor()
|
||||
);
|
||||
|
||||
boost::asio::post(boost::asio::bind_executor(
|
||||
executor,
|
||||
error_handler<HandlerType>{err, std::forward<HandlerType>(handler)}
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Actually execute the statement
|
||||
detail::async_execute_statement(
|
||||
*stmt.channel_,
|
||||
stmt.stmt_msg_.statement_id,
|
||||
params_first,
|
||||
params_last,
|
||||
std::forward<HandlerType>(handler),
|
||||
info
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class Stream>
|
||||
template <class ValueForwardIterator, BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::resultset<Stream>)
|
||||
) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code, boost::mysql::resultset<Stream>)
|
||||
)
|
||||
boost::mysql::prepared_statement<Stream>::async_execute(
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
output_info.clear();
|
||||
assert(valid());
|
||||
|
||||
// Check we got passed the right number of params
|
||||
error_code err;
|
||||
check_num_params(params.first(), params.last(), err, output_info);
|
||||
|
||||
return boost::asio::async_initiate<CompletionToken, void(error_code, resultset<Stream>)>(
|
||||
async_execute_initiation(),
|
||||
token,
|
||||
err,
|
||||
std::ref(output_info),
|
||||
std::ref(*this),
|
||||
params.first(),
|
||||
params.last()
|
||||
);
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::prepared_statement<Stream>::close(
|
||||
error_code& code,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
assert(valid());
|
||||
detail::clear_errors(code, info);
|
||||
detail::close_statement(*channel_, id(), code, info);
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::prepared_statement<Stream>::close()
|
||||
{
|
||||
assert(valid());
|
||||
detail::error_block blk;
|
||||
detail::close_statement(*channel_, id(), blk.err, blk.info);
|
||||
blk.check();
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
boost::mysql::prepared_statement<Stream>::async_close(
|
||||
error_info& output_info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
assert(valid());
|
||||
output_info.clear();
|
||||
return detail::async_close_statement(
|
||||
*channel_,
|
||||
id(),
|
||||
std::forward<CompletionToken>(token),
|
||||
output_info
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_IMPL_PREPARED_STATEMENT_HPP_ */
|
||||
@@ -43,10 +43,6 @@ class prepared_statement
|
||||
{
|
||||
bool valid_ {false};
|
||||
detail::com_stmt_prepare_ok_packet stmt_msg_;
|
||||
|
||||
template <class ValueForwardIterator>
|
||||
void check_num_params(ValueForwardIterator first, ValueForwardIterator last, error_code& err, error_info& info) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief Default constructor.
|
||||
|
||||
Reference in New Issue
Block a user