mirror of
https://github.com/boostorg/mysql.git
synced 2026-02-13 12:32:18 +00:00
clang-format for headers
This commit is contained in:
169
.clang-format
Normal file
169
.clang-format
Normal file
@@ -0,0 +1,169 @@
|
||||
---
|
||||
Language: Cpp
|
||||
ColumnLimit: 100
|
||||
IndentWidth: 4
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
AccessModifierOffset: -4
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
AlignAfterOpenBracket: BlockIndent
|
||||
PointerAlignment: Left
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^<boost/mysql/.*\.hpp>'
|
||||
Priority: -8
|
||||
SortPriority: 0
|
||||
- Regex: '^<boost/.*\.hpp>'
|
||||
Priority: -7
|
||||
SortPriority: 0
|
||||
- Regex: "^<.*"
|
||||
Priority: -6
|
||||
SortPriority: 0
|
||||
- Regex: ".*"
|
||||
Priority: -5
|
||||
SortPriority: 0
|
||||
IndentCaseLabels: false
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlignArrayOfStructures: Left
|
||||
DerivePointerAlignment: false
|
||||
PenaltyBreakAssignment: 2000000
|
||||
PenaltyBreakBeforeFirstCallParameter: 0
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200000000
|
||||
|
||||
# Defaults (based on Google)
|
||||
AlignConsecutiveMacros: false
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
CommentPragmas: "^ IWYU pragma:"
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeIsMainRegex: "([-_](test|unittest))?$"
|
||||
IncludeIsMainSourceRegex: ""
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ""
|
||||
MacroBlockEnd: ""
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Never
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
RawStringFormats:
|
||||
- Language: Cpp
|
||||
Delimiters:
|
||||
- cc
|
||||
- CC
|
||||
- cpp
|
||||
- Cpp
|
||||
- CPP
|
||||
- "c++"
|
||||
- "C++"
|
||||
CanonicalDelimiter: ""
|
||||
BasedOnStyle: google
|
||||
- Language: TextProto
|
||||
Delimiters:
|
||||
- pb
|
||||
- PB
|
||||
- proto
|
||||
- PROTO
|
||||
EnclosingFunctions:
|
||||
- EqualsProto
|
||||
- EquivToProto
|
||||
- PARSE_PARTIAL_TEXT_PROTO
|
||||
- PARSE_TEST_PROTO
|
||||
- PARSE_TEXT_PROTO
|
||||
- ParseTextOrDie
|
||||
- ParseTextProtoOrDie
|
||||
CanonicalDelimiter: ""
|
||||
BasedOnStyle: google
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
Standard: Auto
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
---
|
||||
|
||||
@@ -55,6 +55,7 @@ target_link_libraries(
|
||||
)
|
||||
target_include_directories(
|
||||
boost_mysql
|
||||
SYSTEM # TODO: review this
|
||||
INTERFACE
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
|
||||
@@ -20,8 +20,7 @@ public:
|
||||
const char* what() const noexcept override { return "bad_value_access"; }
|
||||
};
|
||||
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -245,9 +245,7 @@ enum class collation : std::uint16_t
|
||||
gb18030_unicode_520_ci = 250
|
||||
};
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,14 +10,16 @@
|
||||
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
|
||||
#ifndef BOOST_MYSQL_DOXYGEN // For some arcane reason, Doxygen fails to expand Asio macros without this
|
||||
#ifndef BOOST_MYSQL_DOXYGEN // For some arcane reason, Doxygen fails to expand Asio macros without
|
||||
// this
|
||||
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/detail/protocol/protocol_types.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/handshake_params.hpp>
|
||||
#include <boost/mysql/resultset.hpp>
|
||||
#include <boost/mysql/statement.hpp>
|
||||
#include <boost/mysql/handshake_params.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#endif
|
||||
@@ -54,9 +56,7 @@ namespace mysql {
|
||||
* In particular, it is __not__ allowed to call [refmem connection handshake]
|
||||
* on a moved-from connection in order to re-open it.
|
||||
*/
|
||||
template <
|
||||
class Stream
|
||||
>
|
||||
template <class Stream>
|
||||
class connection
|
||||
{
|
||||
std::unique_ptr<detail::channel<Stream>> channel_;
|
||||
@@ -72,36 +72,36 @@ class connection
|
||||
return *channel_;
|
||||
}
|
||||
error_info& shared_info() noexcept { return get_channel().shared_info(); }
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief Initializing constructor.
|
||||
* \details
|
||||
* As part of the initialization, a Stream object is created
|
||||
* by forwarding any passed in arguments to its constructor.
|
||||
*
|
||||
*
|
||||
* The constructed connection will have [refmem connection valid]
|
||||
* return `true`.
|
||||
*/
|
||||
template<
|
||||
template <
|
||||
class... Args,
|
||||
class EnableIf = typename std::enable_if<std::is_constructible<Stream, Args...>::value>::type
|
||||
>
|
||||
connection(Args&&... args) :
|
||||
channel_(new detail::channel<Stream>(std::forward<Args>(args)...))
|
||||
class EnableIf =
|
||||
typename std::enable_if<std::is_constructible<Stream, Args...>::value>::type>
|
||||
connection(Args&&... args) : channel_(new detail::channel<Stream>(std::forward<Args>(args)...))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Move constructor.
|
||||
* \details The constructed connection will be valid if `other` is valid.
|
||||
* After this operation, `other` is guaranteed to be invalid.
|
||||
*/
|
||||
* \brief Move constructor.
|
||||
* \details The constructed connection will be valid if `other` is valid.
|
||||
* After this operation, `other` is guaranteed to be invalid.
|
||||
*/
|
||||
connection(connection&& other) = default;
|
||||
|
||||
/**
|
||||
* \brief Move assignment.
|
||||
* \details The assigned-to connection will be valid if `other` is valid.
|
||||
*/
|
||||
* \brief Move assignment.
|
||||
* \details The assigned-to connection will be valid if `other` is valid.
|
||||
*/
|
||||
connection& operator=(connection&& rhs) = default;
|
||||
|
||||
#ifndef BOOST_MYSQL_DOXYGEN
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
/**
|
||||
* \brief Returns whether the connection uses SSL or not.
|
||||
* \details This function always returns `false` if the underlying
|
||||
* stream does not support SSL. This function always returns `false`
|
||||
* stream does not support SSL. This function always returns `false`
|
||||
* for connections that haven't been
|
||||
* established yet (handshake not run yet). If the handshake fails,
|
||||
* the return value is undefined.
|
||||
@@ -149,7 +149,6 @@ public:
|
||||
*/
|
||||
bool uses_ssl() const noexcept { return get_channel().ssl_active(); }
|
||||
|
||||
|
||||
/**
|
||||
* \brief Performs a connection to the MySQL server (sync with error code version).
|
||||
* \details This function is only available if `Stream` satisfies the
|
||||
@@ -166,7 +165,7 @@ public:
|
||||
void connect(
|
||||
const EndpointType& endpoint,
|
||||
const handshake_params& params,
|
||||
error_code& ec,
|
||||
error_code& ec,
|
||||
error_info& info
|
||||
);
|
||||
|
||||
@@ -183,10 +182,7 @@ public:
|
||||
* See [link mysql.ssl.handshake this section] for more info.
|
||||
*/
|
||||
template <typename EndpointType>
|
||||
void connect(
|
||||
const EndpointType& endpoint,
|
||||
const handshake_params& params
|
||||
);
|
||||
void connect(const EndpointType& endpoint, const handshake_params& params);
|
||||
|
||||
/**
|
||||
* \brief Performs a connection to the MySQL server
|
||||
@@ -210,9 +206,7 @@ public:
|
||||
template <
|
||||
typename EndpointType,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_connect(
|
||||
const EndpointType& endpoint,
|
||||
@@ -220,7 +214,12 @@ public:
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_connect(endpoint, params, this->shared_info(), std::forward<CompletionToken>(token));
|
||||
return async_connect(
|
||||
endpoint,
|
||||
params,
|
||||
this->shared_info(),
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -245,9 +244,7 @@ public:
|
||||
template <
|
||||
typename EndpointType,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_connect(
|
||||
const EndpointType& endpoint,
|
||||
@@ -258,7 +255,7 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Performs the MySQL-level handshake (sync with error code version).
|
||||
* \details Does not connect the underlying stream.
|
||||
* \details Does not connect the underlying stream.
|
||||
* If the `Stream` template parameter fulfills the __SocketConnection__
|
||||
* requirements, use [refmem connection connect] instead of this function.
|
||||
*
|
||||
@@ -292,11 +289,8 @@ public:
|
||||
*
|
||||
* The handler signature for this operation is `void(boost::mysql::error_code)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_handshake(
|
||||
const handshake_params& params,
|
||||
@@ -320,11 +314,8 @@ public:
|
||||
*
|
||||
* The handler signature for this operation is `void(boost::mysql::error_code)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_handshake(
|
||||
const handshake_params& params,
|
||||
@@ -340,7 +331,8 @@ public:
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*/
|
||||
void query(boost::string_view query_string, resultset<Stream>& result, error_code&, error_info&);
|
||||
void
|
||||
query(boost::string_view query_string, resultset<Stream>& result, error_code&, error_info&);
|
||||
|
||||
/**
|
||||
* \brief Executes a SQL text query (sync with exceptions version).
|
||||
@@ -363,11 +355,8 @@ public:
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset_base<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_query(
|
||||
boost::string_view query_string,
|
||||
@@ -375,7 +364,12 @@ public:
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_query(query_string, result, shared_info(), std::forward<CompletionToken>(token));
|
||||
return async_query(
|
||||
query_string,
|
||||
result,
|
||||
shared_info(),
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,11 +383,8 @@ public:
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset_base<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_query(
|
||||
boost::string_view query_string,
|
||||
@@ -408,7 +399,8 @@ public:
|
||||
* Prepared statements are only valid while the connection object on which
|
||||
* this function was called is alive and open.
|
||||
*/
|
||||
void prepare_statement(boost::string_view stmt, statement<Stream>& result, error_code&, error_info&);
|
||||
void
|
||||
prepare_statement(boost::string_view stmt, statement<Stream>& result, error_code&, error_info&);
|
||||
|
||||
/**
|
||||
* \brief Prepares a statement (sync with exceptions version).
|
||||
@@ -427,11 +419,8 @@ public:
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::statement_base<Stream>)`
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_prepare_statement(
|
||||
boost::string_view stmt,
|
||||
@@ -439,7 +428,12 @@ public:
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_prepare_statement(stmt, result, shared_info(), std::forward<CompletionToken>(token));
|
||||
return async_prepare_statement(
|
||||
stmt,
|
||||
result,
|
||||
shared_info(),
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -451,11 +445,8 @@ public:
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::statement_base<Stream>)`
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_prepare_statement(
|
||||
boost::string_view stmt,
|
||||
@@ -464,10 +455,9 @@ public:
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Closes the connection (sync with error code version).
|
||||
* \details
|
||||
* \details
|
||||
* This function is only available if `Stream` satisfies the
|
||||
* [reflink SocketStream] requirements.
|
||||
*
|
||||
@@ -478,7 +468,7 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Closes the connection (sync with exceptions version).
|
||||
* \details
|
||||
* \details
|
||||
* This function is only available if `Stream` satisfies the
|
||||
* [reflink SocketStream] requirements.
|
||||
*
|
||||
@@ -489,7 +479,7 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Closes the connection (async without [reflink error_info] version).
|
||||
* \details
|
||||
* \details
|
||||
* This function is only available if `Stream` satisfies the
|
||||
* [reflink SocketStream] requirements.
|
||||
*
|
||||
@@ -498,11 +488,8 @@ public:
|
||||
*
|
||||
* The handler signature for this operation is `void(boost::mysql::error_code)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_close(CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||
{
|
||||
@@ -511,7 +498,7 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Closes the connection (async with [reflink error_info] version).
|
||||
* \details
|
||||
* \details
|
||||
* This function is only available if `Stream` satisfies the
|
||||
* [reflink SocketStream] requirements.
|
||||
*
|
||||
@@ -520,24 +507,20 @@ public:
|
||||
*
|
||||
* The handler signature for this operation is `void(boost::mysql::error_code)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_close(
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Notifies the MySQL server that the client wants to end the session
|
||||
* (sync with error code version).
|
||||
*
|
||||
* \details Sends a quit request to the MySQL server. If the connection is using SSL,
|
||||
* this function will also perform the SSL shutdown. You should
|
||||
* this function will also perform the SSL shutdown. You should
|
||||
* close the underlying physical connection after calling this function.
|
||||
*
|
||||
* If the `Stream` template parameter fulfills the __SocketConnection__
|
||||
@@ -552,7 +535,7 @@ public:
|
||||
* (sync with exceptions version).
|
||||
*
|
||||
* \details Sends a quit request to the MySQL server. If the connection is using SSL,
|
||||
* this function will also perform the SSL shutdown. You should
|
||||
* this function will also perform the SSL shutdown. You should
|
||||
* close the underlying physical connection after calling this function.
|
||||
*
|
||||
* If the `Stream` template parameter fulfills the __SocketConnection__
|
||||
@@ -566,7 +549,7 @@ public:
|
||||
* (async without [reflink error_info] version).
|
||||
*
|
||||
* \details Sends a quit request to the MySQL server. If the connection is using SSL,
|
||||
* this function will also perform the SSL shutdown. You should
|
||||
* this function will also perform the SSL shutdown. You should
|
||||
* close the underlying physical connection after calling this function.
|
||||
*
|
||||
* If the `Stream` template parameter fulfills the __SocketConnection__
|
||||
@@ -575,11 +558,8 @@ public:
|
||||
*
|
||||
* The handler signature for this operation is `void(boost::mysql::error_code)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_quit(CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||
{
|
||||
@@ -591,7 +571,7 @@ public:
|
||||
* (async with [reflink error_info] version).
|
||||
*
|
||||
* \details Sends a quit request to the MySQL server. If the connection is using SSL,
|
||||
* this function will also perform the SSL shutdown. You should
|
||||
* this function will also perform the SSL shutdown. You should
|
||||
* close the underlying physical connection after calling this function.
|
||||
*
|
||||
* If the `Stream` template parameter fulfills the __SocketConnection__
|
||||
@@ -600,11 +580,8 @@ public:
|
||||
*
|
||||
* The handler signature for this operation is `void(boost::mysql::error_code)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_quit(
|
||||
error_info& output_info,
|
||||
@@ -618,8 +595,8 @@ constexpr unsigned short default_port = 3306;
|
||||
/// The default TCP port for the MySQL protocol, as a string. Useful for hostname resolution.
|
||||
constexpr const char* default_port_string = "3306";
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/impl/connection.hpp>
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
#ifndef BOOST_MYSQL_DATETIME_TYPES_HPP
|
||||
#define BOOST_MYSQL_DATETIME_TYPES_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
|
||||
@@ -31,16 +32,17 @@ using datetime = std::chrono::time_point<std::chrono::system_clock, std::chrono:
|
||||
using time = std::chrono::microseconds;
|
||||
|
||||
/// The minimum allowed value for [reflink date] (0000-01-01).
|
||||
BOOST_CXX14_CONSTEXPR const date min_date { days(-719528) };
|
||||
BOOST_CXX14_CONSTEXPR const date min_date{days(-719528)};
|
||||
|
||||
/// The maximum allowed value for [reflink date] (9999-12-31).
|
||||
BOOST_CXX14_CONSTEXPR const date max_date { days(2932896) };
|
||||
BOOST_CXX14_CONSTEXPR const date max_date{days(2932896)};
|
||||
|
||||
/// The minimum allowed value for [reflink datetime].
|
||||
BOOST_CXX14_CONSTEXPR const datetime min_datetime = min_date;
|
||||
|
||||
/// The maximum allowed value for [reflink datetime].
|
||||
BOOST_CXX14_CONSTEXPR const datetime max_datetime = max_date + std::chrono::hours(24) - std::chrono::microseconds(1);
|
||||
BOOST_CXX14_CONSTEXPR const datetime max_datetime =
|
||||
max_date + std::chrono::hours(24) - std::chrono::microseconds(1);
|
||||
|
||||
/// The minimum allowed value for [reflink time].
|
||||
constexpr time min_time = -std::chrono::hours(839);
|
||||
@@ -48,7 +50,7 @@ constexpr time min_time = -std::chrono::hours(839);
|
||||
/// The maximum allowed value for [reflink time].
|
||||
constexpr time max_time = std::chrono::hours(839);
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_AUTH_AUTH_CALCULATOR_HPP
|
||||
#define BOOST_MYSQL_DETAIL_AUTH_AUTH_CALCULATOR_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -33,10 +35,11 @@ struct authentication_plugin
|
||||
|
||||
class auth_calculator
|
||||
{
|
||||
const authentication_plugin* plugin_ {nullptr};
|
||||
const authentication_plugin* plugin_{nullptr};
|
||||
bytestring response_;
|
||||
|
||||
inline static const authentication_plugin* find_plugin(boost::string_view name);
|
||||
|
||||
public:
|
||||
inline error_code calculate(
|
||||
boost::string_view plugin_name,
|
||||
@@ -46,7 +49,10 @@ public:
|
||||
);
|
||||
boost::string_view response() const noexcept
|
||||
{
|
||||
return boost::string_view(reinterpret_cast<const char*>(response_.data()), response_.size());
|
||||
return boost::string_view(
|
||||
reinterpret_cast<const char*>(response_.data()),
|
||||
response_.size()
|
||||
);
|
||||
}
|
||||
boost::string_view plugin_name() const noexcept
|
||||
{
|
||||
@@ -55,9 +61,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/auth/impl/auth_calculator.ipp>
|
||||
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_AUTH_CACHING_SHA2_PASSWORD_HPP
|
||||
#define BOOST_MYSQL_DETAIL_AUTH_CACHING_SHA2_PASSWORD_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
@@ -34,10 +36,10 @@ inline error_code compute_response(
|
||||
bytestring& output
|
||||
);
|
||||
|
||||
} // caching_sha2_password
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace caching_sha2_password
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/auth/impl/caching_sha2_password.ipp>
|
||||
|
||||
|
||||
@@ -11,55 +11,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/auth/auth_calculator.hpp>
|
||||
#include <boost/mysql/detail/auth/mysql_native_password.hpp>
|
||||
#include <boost/mysql/detail/auth/caching_sha2_password.hpp>
|
||||
#include <boost/mysql/detail/auth/mysql_native_password.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/make_string_view.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
constexpr authentication_plugin mysql_native_password_plugin {
|
||||
constexpr authentication_plugin mysql_native_password_plugin{
|
||||
make_string_view("mysql_native_password"),
|
||||
&mysql_native_password::compute_response
|
||||
};
|
||||
&mysql_native_password::compute_response};
|
||||
|
||||
constexpr authentication_plugin caching_sha2_password_plugin {
|
||||
constexpr authentication_plugin caching_sha2_password_plugin{
|
||||
make_string_view("caching_sha2_password"),
|
||||
&caching_sha2_password::compute_response
|
||||
};
|
||||
&caching_sha2_password::compute_response};
|
||||
|
||||
constexpr std::array<const authentication_plugin*, 2> all_authentication_plugins {{
|
||||
constexpr const authentication_plugin* all_authentication_plugins[] = {
|
||||
&mysql_native_password_plugin,
|
||||
&caching_sha2_password_plugin
|
||||
}};
|
||||
&caching_sha2_password_plugin};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
inline const boost::mysql::detail::authentication_plugin*
|
||||
boost::mysql::detail::auth_calculator::find_plugin(
|
||||
boost::string_view name
|
||||
)
|
||||
boost::mysql::detail::auth_calculator::find_plugin(boost::string_view name)
|
||||
{
|
||||
auto it = std::find_if(
|
||||
all_authentication_plugins.begin(),
|
||||
all_authentication_plugins.end(),
|
||||
std::begin(all_authentication_plugins),
|
||||
std::end(all_authentication_plugins),
|
||||
[name](const authentication_plugin* plugin) { return plugin->name == name; }
|
||||
);
|
||||
return it == std::end(all_authentication_plugins) ? nullptr : *it;
|
||||
}
|
||||
|
||||
inline boost::mysql::error_code
|
||||
boost::mysql::detail::auth_calculator::calculate(
|
||||
inline boost::mysql::error_code boost::mysql::detail::auth_calculator::calculate(
|
||||
boost::string_view plugin_name,
|
||||
boost::string_view password,
|
||||
boost::string_view challenge,
|
||||
bool use_ssl
|
||||
)
|
||||
{
|
||||
|
||||
plugin_ = find_plugin(plugin_name);
|
||||
if (plugin_)
|
||||
{
|
||||
@@ -80,6 +73,4 @@ boost::mysql::detail::auth_calculator::calculate(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_AUTH_IMPL_AUTH_CALCULATOR_IPP_ */
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <cstring>
|
||||
#include <boost/mysql/detail/auxiliar/make_string_view.hpp>
|
||||
#include <boost/mysql/detail/auth/caching_sha2_password.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/make_string_view.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -27,22 +28,18 @@ constexpr boost::string_view perform_full_auth = make_string_view("\4");
|
||||
|
||||
// challenge must point to challenge_length bytes of data
|
||||
// output must point to response_length bytes of data
|
||||
inline void compute_auth_string(
|
||||
boost::string_view password,
|
||||
const void* challenge,
|
||||
void* output
|
||||
)
|
||||
inline void compute_auth_string(boost::string_view password, const void* challenge, void* output)
|
||||
{
|
||||
static_assert(response_length == SHA256_DIGEST_LENGTH, "Buffer size mismatch");
|
||||
|
||||
// SHA(SHA(password_sha) concat challenge) XOR password_sha
|
||||
// hash1 = SHA(pass)
|
||||
using sha_buffer = std::uint8_t [response_length];
|
||||
using sha_buffer = std::uint8_t[response_length];
|
||||
sha_buffer password_sha;
|
||||
SHA256(reinterpret_cast<const unsigned char*>(password.data()), password.size(), password_sha);
|
||||
|
||||
// SHA(password_sha) concat challenge = buffer
|
||||
std::uint8_t buffer [response_length + challenge_length];
|
||||
std::uint8_t buffer[response_length + challenge_length];
|
||||
SHA256(password_sha, response_length, buffer);
|
||||
std::memcpy(buffer + response_length, challenge, challenge_length);
|
||||
|
||||
@@ -57,15 +54,12 @@ inline void compute_auth_string(
|
||||
}
|
||||
}
|
||||
|
||||
} // caching_sha2_password
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace caching_sha2_password
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
|
||||
|
||||
inline boost::mysql::error_code
|
||||
boost::mysql::detail::caching_sha2_password::compute_response(
|
||||
inline boost::mysql::error_code boost::mysql::detail::caching_sha2_password::compute_response(
|
||||
boost::string_view password,
|
||||
boost::string_view challenge,
|
||||
bool use_ssl,
|
||||
@@ -92,14 +86,9 @@ boost::mysql::detail::caching_sha2_password::compute_response(
|
||||
|
||||
// Do the calculation
|
||||
output.resize(response_length);
|
||||
compute_auth_string(
|
||||
password,
|
||||
challenge.data(),
|
||||
output.data()
|
||||
);
|
||||
compute_auth_string(password, challenge.data(), output.data());
|
||||
return error_code();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_AUTH_IMPL_CACHING_SHA2_PASSWORD_IPP_ */
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <cstring>
|
||||
#include <boost/mysql/detail/auth/mysql_native_password.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
@@ -25,19 +26,15 @@ constexpr std::size_t response_length = 20;
|
||||
// challenge must point to challenge_length bytes of data
|
||||
// output must point to response_length bytes of data
|
||||
// SHA1( password ) XOR SHA1( "20-bytes random data from server" <concat> SHA1( SHA1( password ) ) )
|
||||
inline void compute_auth_string(
|
||||
boost::string_view password,
|
||||
const void* challenge,
|
||||
void* output
|
||||
)
|
||||
inline void compute_auth_string(boost::string_view password, const void* challenge, void* output)
|
||||
{
|
||||
// SHA1 (password)
|
||||
using sha1_buffer = unsigned char [SHA_DIGEST_LENGTH];
|
||||
using sha1_buffer = unsigned char[SHA_DIGEST_LENGTH];
|
||||
sha1_buffer password_sha1;
|
||||
SHA1(reinterpret_cast<const unsigned char*>(password.data()), password.size(), password_sha1);
|
||||
|
||||
// Add server challenge (salt)
|
||||
unsigned char salted_buffer [challenge_length + SHA_DIGEST_LENGTH];
|
||||
unsigned char salted_buffer[challenge_length + SHA_DIGEST_LENGTH];
|
||||
memcpy(salted_buffer, challenge, challenge_length);
|
||||
SHA1(password_sha1, sizeof(password_sha1), salted_buffer + 20);
|
||||
sha1_buffer salted_sha1;
|
||||
@@ -51,17 +48,15 @@ inline void compute_auth_string(
|
||||
}
|
||||
}
|
||||
|
||||
} // mysql_native_password
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace mysql_native_password
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
|
||||
inline boost::mysql::error_code
|
||||
boost::mysql::detail::mysql_native_password::compute_response(
|
||||
inline boost::mysql::error_code boost::mysql::detail::mysql_native_password::compute_response(
|
||||
boost::string_view password,
|
||||
boost::string_view challenge,
|
||||
bool, // use_ssl
|
||||
bool, // use_ssl
|
||||
bytestring& output
|
||||
)
|
||||
{
|
||||
@@ -73,14 +68,8 @@ boost::mysql::detail::mysql_native_password::compute_response(
|
||||
|
||||
// Do the calculation
|
||||
output.resize(response_length);
|
||||
compute_auth_string(
|
||||
password,
|
||||
challenge.data(),
|
||||
output.data()
|
||||
);
|
||||
compute_auth_string(password, challenge.data(), output.data());
|
||||
return error_code();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_AUTH_MYSQL_NATIVE_PASSWORD_HPP
|
||||
#define BOOST_MYSQL_DETAIL_AUTH_MYSQL_NATIVE_PASSWORD_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
@@ -27,11 +29,10 @@ inline error_code compute_response(
|
||||
bytestring& output
|
||||
);
|
||||
|
||||
|
||||
} // mysql_native_password
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace mysql_native_password
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/auth/impl/mysql_native_password.ipp>
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_AUXILIAR_BYTESTRING_HPP
|
||||
#define BOOST_MYSQL_DETAIL_AUXILIAR_BYTESTRING_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -20,10 +20,8 @@ using basic_bytestring = std::vector<std::uint8_t, Allocator>;
|
||||
|
||||
using bytestring = std::vector<std::uint8_t>;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_AUXILIAR_BYTESTRING_HPP_ */
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_AUXILIAR_FIELD_IMPL_HPP
|
||||
#define BOOST_MYSQL_DETAIL_AUXILIAR_FIELD_IMPL_HPP
|
||||
|
||||
#include <boost/mysql/field_kind.hpp>
|
||||
#include <boost/mysql/datetime_types.hpp>
|
||||
#include <boost/mysql/bad_field_access.hpp>
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/mysql/datetime_types.hpp>
|
||||
#include <boost/mysql/field_kind.hpp>
|
||||
|
||||
#include <boost/mp11.hpp>
|
||||
#include <boost/variant2/variant.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -24,26 +26,29 @@ namespace detail {
|
||||
struct field_impl
|
||||
{
|
||||
using null_t = boost::variant2::monostate;
|
||||
|
||||
|
||||
using variant_type = boost::variant2::variant<
|
||||
null_t, // Any of the below when the value is NULL
|
||||
std::int64_t, // signed TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT
|
||||
std::uint64_t, // unsigned TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, YEAR, BIT
|
||||
std::string, // CHAR, VARCHAR, BINARY, VARBINARY, TEXT (all sizes), BLOB (all sizes), ENUM, SET, DECIMAL, GEOMTRY
|
||||
float, // FLOAT
|
||||
double, // DOUBLE
|
||||
date, // DATE
|
||||
datetime, // DATETIME, TIMESTAMP
|
||||
time // TIME
|
||||
>;
|
||||
null_t, // Any of the below when the value is NULL
|
||||
std::int64_t, // signed TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT
|
||||
std::uint64_t, // unsigned TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, YEAR, BIT
|
||||
std::string, // CHAR, VARCHAR, BINARY, VARBINARY, TEXT (all sizes), BLOB (all sizes), ENUM,
|
||||
// SET, DECIMAL, GEOMTRY
|
||||
float, // FLOAT
|
||||
double, // DOUBLE
|
||||
date, // DATE
|
||||
datetime, // DATETIME, TIMESTAMP
|
||||
time // TIME
|
||||
>;
|
||||
|
||||
variant_type data;
|
||||
|
||||
field_impl() = default;
|
||||
|
||||
template <typename... Args>
|
||||
field_impl(Args&&... args) noexcept(std::is_nothrow_constructible<variant_type, Args...>::value) :
|
||||
data (std::forward<Args>(args)...) {}
|
||||
field_impl(Args&&... args) noexcept(std::is_nothrow_constructible<variant_type, Args...>::value)
|
||||
: data(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
field_kind kind() const noexcept { return static_cast<field_kind>(data.index()); }
|
||||
|
||||
@@ -80,8 +85,8 @@ struct field_impl
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_AUXILIAR_FIELD_TYPE_TRAITS_HPP
|
||||
#define BOOST_MYSQL_DETAIL_AUXILIAR_FIELD_TYPE_TRAITS_HPP
|
||||
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/void_t.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
@@ -19,8 +20,11 @@ namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct is_field_view_forward_iterator : std::false_type { };
|
||||
struct is_field_view_forward_iterator : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
template <typename T>
|
||||
struct is_field_view_forward_iterator<T, void_t<
|
||||
typename std::enable_if<
|
||||
@@ -36,10 +40,14 @@ struct is_field_view_forward_iterator<T, void_t<
|
||||
>::value
|
||||
>::type
|
||||
>> : std::true_type { };
|
||||
// clang-format on
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct is_field_view_collection : std::false_type {};
|
||||
struct is_field_view_collection : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
template <typename T>
|
||||
struct is_field_view_collection<T, void_t<
|
||||
typename std::enable_if<
|
||||
@@ -49,19 +57,19 @@ struct is_field_view_collection<T, void_t<
|
||||
is_field_view_forward_iterator<decltype(std::end(std::declval<const T&>()))>::value
|
||||
>::type
|
||||
>> : std::true_type {};
|
||||
|
||||
// clang-format on
|
||||
|
||||
// Helpers
|
||||
template <typename T>
|
||||
using enable_if_field_view_forward_iterator = typename std::enable_if<is_field_view_forward_iterator<T>::value>::type;
|
||||
using enable_if_field_view_forward_iterator =
|
||||
typename std::enable_if<is_field_view_forward_iterator<T>::value>::type;
|
||||
|
||||
template <typename T>
|
||||
using enable_if_field_view_collection = typename std::enable_if<is_field_view_collection<T>::value>::type;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
using enable_if_field_view_collection =
|
||||
typename std::enable_if<is_field_view_collection<T>::value>::type;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -12,28 +12,19 @@
|
||||
|
||||
#include <boost/mysql/detail/auxiliar/row_base.hpp>
|
||||
|
||||
|
||||
boost::mysql::detail::row_base::row_base(
|
||||
const field_view* fields,
|
||||
std::size_t size
|
||||
) :
|
||||
fields_(fields, fields + size)
|
||||
boost::mysql::detail::row_base::row_base(const field_view* fields, std::size_t size)
|
||||
: fields_(fields, fields + size)
|
||||
{
|
||||
copy_strings();
|
||||
}
|
||||
|
||||
boost::mysql::detail::row_base::row_base(
|
||||
const row_base& rhs
|
||||
) :
|
||||
fields_(rhs.fields_),
|
||||
string_buffer_(rhs.string_buffer_)
|
||||
boost::mysql::detail::row_base::row_base(const row_base& rhs)
|
||||
: fields_(rhs.fields_), string_buffer_(rhs.string_buffer_)
|
||||
{
|
||||
rebase_strings(rhs.string_buffer_.data());
|
||||
}
|
||||
|
||||
boost::mysql::detail::row_base& boost::mysql::detail::row_base::operator=(
|
||||
const row_base& rhs
|
||||
)
|
||||
boost::mysql::detail::row_base& boost::mysql::detail::row_base::operator=(const row_base& rhs)
|
||||
{
|
||||
fields_ = rhs.fields_;
|
||||
string_buffer_ = rhs.string_buffer_;
|
||||
@@ -41,21 +32,16 @@ boost::mysql::detail::row_base& boost::mysql::detail::row_base::operator=(
|
||||
return *this;
|
||||
}
|
||||
|
||||
void boost::mysql::detail::row_base::assign(
|
||||
const field_view* fields,
|
||||
std::size_t size
|
||||
)
|
||||
void boost::mysql::detail::row_base::assign(const field_view* fields, std::size_t size)
|
||||
{
|
||||
fields_.assign(fields, fields + size);
|
||||
copy_strings();
|
||||
}
|
||||
|
||||
inline void boost::mysql::detail::row_base::rebase_strings(
|
||||
const char* old_buffer_base
|
||||
)
|
||||
inline void boost::mysql::detail::row_base::rebase_strings(const char* old_buffer_base)
|
||||
{
|
||||
const char* new_buffer_base = string_buffer_.data();
|
||||
for (auto& f: fields_)
|
||||
for (auto& f : fields_)
|
||||
{
|
||||
if (f.is_string())
|
||||
{
|
||||
@@ -63,10 +49,7 @@ inline void boost::mysql::detail::row_base::rebase_strings(
|
||||
if (!sv.empty())
|
||||
{
|
||||
std::size_t offset = sv.data() - old_buffer_base;
|
||||
f = field_view(boost::string_view(
|
||||
new_buffer_base + offset,
|
||||
sv.size()
|
||||
));
|
||||
f = field_view(boost::string_view(new_buffer_base + offset, sv.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,10 +69,10 @@ inline void boost::mysql::detail::row_base::copy_strings()
|
||||
|
||||
// Make space
|
||||
string_buffer_.resize(size);
|
||||
|
||||
|
||||
// Copy the strings
|
||||
std::size_t offset = 0;
|
||||
for (auto& f: fields_)
|
||||
for (auto& f : fields_)
|
||||
{
|
||||
if (f.is_string())
|
||||
{
|
||||
@@ -104,5 +87,4 @@ inline void boost::mysql::detail::row_base::copy_strings()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,16 +15,14 @@ namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <std::size_t N>
|
||||
constexpr boost::string_view make_string_view(const char(&buff)[N]) noexcept
|
||||
constexpr boost::string_view make_string_view(const char (&buff)[N]) noexcept
|
||||
{
|
||||
static_assert(N>=1, "Expected a C-array literal");
|
||||
return boost::string_view(buff, N-1); // discard null terminator
|
||||
static_assert(N >= 1, "Expected a C-array literal");
|
||||
return boost::string_view(buff, N - 1); // discard null terminator
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define BOOST_MYSQL_DETAIL_AUXILIAR_ROW_BASE_HPP
|
||||
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
@@ -33,16 +34,22 @@ public:
|
||||
inline void assign(const field_view* fields, std::size_t size);
|
||||
inline void rebase_strings(const char* old_buffer_base);
|
||||
inline void copy_strings();
|
||||
inline void clear() noexcept { fields_.clear(); string_buffer_.clear(); }
|
||||
inline void clear() noexcept
|
||||
{
|
||||
fields_.clear();
|
||||
string_buffer_.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<field_view> fields_;
|
||||
|
||||
private:
|
||||
std::vector<char> string_buffer_;
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/auxiliar/impl/row_base.ipp>
|
||||
|
||||
|
||||
@@ -8,21 +8,22 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_AUXILIAR_ROWS_ITERATOR_HPP
|
||||
#define BOOST_MYSQL_DETAIL_AUXILIAR_ROWS_ITERATOR_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <boost/mysql/row.hpp>
|
||||
#include <boost/mysql/row_view.hpp>
|
||||
#include <iterator>
|
||||
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <class RowsType> // This can be either rows or rows_view
|
||||
template <class RowsType> // This can be either rows or rows_view
|
||||
class rows_iterator
|
||||
{
|
||||
const RowsType* obj_ {nullptr};
|
||||
std::size_t row_num_ {0};
|
||||
const RowsType* obj_{nullptr};
|
||||
std::size_t row_num_{0};
|
||||
|
||||
public:
|
||||
using value_type = row;
|
||||
using reference = row_view;
|
||||
@@ -33,14 +34,46 @@ public:
|
||||
rows_iterator() = default;
|
||||
rows_iterator(const RowsType* obj, std::size_t rownum) noexcept : obj_(obj), row_num_(rownum) {}
|
||||
|
||||
rows_iterator& operator++() noexcept { ++row_num_; return *this; }
|
||||
rows_iterator operator++(int) noexcept { auto res = *this; ++(*this); return res; }
|
||||
rows_iterator& operator--() noexcept { --row_num_; return *this; }
|
||||
rows_iterator operator--(int) noexcept { auto res = *this; --(*this); return res; }
|
||||
rows_iterator& operator+=(std::ptrdiff_t n) noexcept { row_num_ += n; return *this; }
|
||||
rows_iterator& operator-=(std::ptrdiff_t n) noexcept { row_num_ -= n; return *this; }
|
||||
rows_iterator operator+(std::ptrdiff_t n) const noexcept { return rows_iterator(obj_, row_num_ + n); }
|
||||
rows_iterator operator-(std::ptrdiff_t n) const noexcept { return rows_iterator(obj_, row_num_ - n); }
|
||||
rows_iterator& operator++() noexcept
|
||||
{
|
||||
++row_num_;
|
||||
return *this;
|
||||
}
|
||||
rows_iterator operator++(int) noexcept
|
||||
{
|
||||
auto res = *this;
|
||||
++(*this);
|
||||
return res;
|
||||
}
|
||||
rows_iterator& operator--() noexcept
|
||||
{
|
||||
--row_num_;
|
||||
return *this;
|
||||
}
|
||||
rows_iterator operator--(int) noexcept
|
||||
{
|
||||
auto res = *this;
|
||||
--(*this);
|
||||
return res;
|
||||
}
|
||||
rows_iterator& operator+=(std::ptrdiff_t n) noexcept
|
||||
{
|
||||
row_num_ += n;
|
||||
return *this;
|
||||
}
|
||||
rows_iterator& operator-=(std::ptrdiff_t n) noexcept
|
||||
{
|
||||
row_num_ -= n;
|
||||
return *this;
|
||||
}
|
||||
rows_iterator operator+(std::ptrdiff_t n) const noexcept
|
||||
{
|
||||
return rows_iterator(obj_, row_num_ + n);
|
||||
}
|
||||
rows_iterator operator-(std::ptrdiff_t n) const noexcept
|
||||
{
|
||||
return rows_iterator(obj_, row_num_ - n);
|
||||
}
|
||||
std::ptrdiff_t operator-(rows_iterator rhs) const noexcept { return row_num_ - rhs.row_num_; }
|
||||
|
||||
pointer operator->() const noexcept { return **this; }
|
||||
@@ -61,10 +94,8 @@ rows_iterator<RowsType> operator+(std::ptrdiff_t n, rows_iterator<RowsType> it)
|
||||
return it + n;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
|
||||
// A very simplified variable-length string with fixed max-size
|
||||
|
||||
#include <array>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
@@ -25,8 +26,9 @@ class static_string
|
||||
{
|
||||
std::array<char, max_size> buffer_;
|
||||
std::size_t size_;
|
||||
|
||||
public:
|
||||
static_string() noexcept: size_(0) {}
|
||||
static_string() noexcept : size_(0) {}
|
||||
static_string(boost::string_view value) noexcept : size_(value.size())
|
||||
{
|
||||
assert(value.size() <= max_size);
|
||||
@@ -59,10 +61,8 @@ std::ostream& operator<<(std::ostream& os, const static_string<max_size>& value)
|
||||
return os << value.value();
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_AUXILIAR_STATIC_STRING_HPP_ */
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/utility/string_view_fwd.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -23,10 +24,13 @@ class string_view_offset
|
||||
{
|
||||
std::size_t offset_;
|
||||
std::size_t size_;
|
||||
|
||||
public:
|
||||
constexpr string_view_offset() noexcept : offset_(0), size_(0) {}
|
||||
constexpr string_view_offset(std::size_t offset, std::size_t size) noexcept :
|
||||
offset_(offset), size_(size) {}
|
||||
constexpr string_view_offset(std::size_t offset, std::size_t size) noexcept
|
||||
: offset_(offset), size_(size)
|
||||
{
|
||||
}
|
||||
constexpr std::size_t offset() const noexcept { return offset_; }
|
||||
constexpr std::size_t size() const noexcept { return size_; }
|
||||
constexpr bool operator==(string_view_offset rhs) const noexcept
|
||||
@@ -35,15 +39,18 @@ public:
|
||||
}
|
||||
constexpr bool operator!=(string_view_offset rhs) const noexcept { return !(*this == rhs); }
|
||||
|
||||
static string_view_offset from_sv(boost::string_view from, const std::uint8_t* buffer_first) noexcept
|
||||
static string_view_offset
|
||||
from_sv(boost::string_view from, const std::uint8_t* buffer_first) noexcept
|
||||
{
|
||||
return string_view_offset(from.data() - reinterpret_cast<const char*>(buffer_first), from.size());
|
||||
return string_view_offset(
|
||||
from.data() - reinterpret_cast<const char*>(buffer_first),
|
||||
from.size()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_AUXILIAR_STRINGIZE_HPP
|
||||
#define BOOST_MYSQL_DETAIL_AUXILIAR_STRINGIZE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -32,10 +32,8 @@ std::string stringize(const Types&... inputs)
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_AUXILIAR_STRINGIZE_HPP_ */
|
||||
|
||||
@@ -20,10 +20,7 @@ namespace detail {
|
||||
|
||||
#ifdef BOOST_MYSQL_VALGRIND_TESTS
|
||||
|
||||
inline void valgrind_make_mem_defined(
|
||||
const void* data,
|
||||
std::size_t size
|
||||
)
|
||||
inline void valgrind_make_mem_defined(const void* data, std::size_t size)
|
||||
{
|
||||
VALGRIND_MAKE_MEM_DEFINED(data, size);
|
||||
}
|
||||
@@ -34,14 +31,8 @@ inline void valgrind_make_mem_defined(const void*, std::size_t) noexcept {}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_AUXILIAR_VALGRIND_HPP_ */
|
||||
|
||||
@@ -16,8 +16,7 @@ template <typename...>
|
||||
using void_t = void;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_PROTOCOL_IMPL_SERIALIZATION_HPP_ */
|
||||
|
||||
|
||||
@@ -8,15 +8,17 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_CHANNEL_CHANNEL_HPP
|
||||
#define BOOST_MYSQL_DETAIL_CHANNEL_CHANNEL_HPP
|
||||
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
#include <boost/mysql/detail/protocol/capabilities.hpp>
|
||||
#include <boost/mysql/detail/channel/disableable_ssl_stream.hpp>
|
||||
#include <boost/mysql/detail/channel/message_reader.hpp>
|
||||
#include <boost/mysql/detail/channel/message_writer.hpp>
|
||||
#include <boost/mysql/detail/protocol/capabilities.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -25,7 +27,6 @@ namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
|
||||
// Implements the message layer of the MySQL protocol
|
||||
template <class Stream>
|
||||
class channel
|
||||
@@ -35,16 +36,15 @@ class channel
|
||||
message_reader reader_;
|
||||
message_writer writer_;
|
||||
|
||||
std::uint8_t shared_sequence_number_ {}; // for async ops
|
||||
bytestring shared_buff_; // for async ops
|
||||
error_info shared_info_; // for async ops
|
||||
std::vector<field_view> shared_fields_; // for read_some ops
|
||||
std::uint8_t shared_sequence_number_{}; // for async ops
|
||||
bytestring shared_buff_; // for async ops
|
||||
error_info shared_info_; // for async ops
|
||||
std::vector<field_view> shared_fields_; // for read_some ops
|
||||
public:
|
||||
// TODO: use this arg
|
||||
template <class... Args>
|
||||
channel(std::size_t read_buffer_size, Args&&... args) :
|
||||
stream_(std::forward<Args>(args)...),
|
||||
reader_(read_buffer_size)
|
||||
channel(std::size_t read_buffer_size, Args&&... args)
|
||||
: stream_(std::forward<Args>(args)...), reader_(read_buffer_size)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -65,27 +65,30 @@ public:
|
||||
return reader_.read_some(stream_, code, keep_messages);
|
||||
}
|
||||
|
||||
template<
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_read_some(CompletionToken&& token, bool keep_messages = false)
|
||||
{
|
||||
return reader_.async_read_some(stream_, std::forward<CompletionToken>(token), keep_messages);
|
||||
return reader_
|
||||
.async_read_some(stream_, std::forward<CompletionToken>(token), keep_messages);
|
||||
}
|
||||
|
||||
boost::asio::const_buffer read_one(std::uint8_t& seqnum, error_code& ec, bool keep_messages = false)
|
||||
boost::asio::const_buffer
|
||||
read_one(std::uint8_t& seqnum, error_code& ec, bool keep_messages = false)
|
||||
{
|
||||
return reader_.read_one(stream_, seqnum, ec, keep_messages);
|
||||
}
|
||||
|
||||
template<
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code, ::boost::asio::const_buffer)) CompletionToken
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, ::boost::asio::const_buffer))
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code, ::boost::asio::const_buffer))
|
||||
CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(error_code, ::boost::asio::const_buffer)
|
||||
)
|
||||
async_read_one(std::uint8_t& seqnum, CompletionToken&& token, bool keep_messages = false)
|
||||
{
|
||||
return reader_.async_read_one(stream_, seqnum, std::forward<CompletionToken>(token), keep_messages);
|
||||
return reader_
|
||||
.async_read_one(stream_, seqnum, std::forward<CompletionToken>(token), keep_messages);
|
||||
}
|
||||
|
||||
// Writing
|
||||
@@ -94,24 +97,19 @@ public:
|
||||
writer_.write(stream_, buffer, seqnum, code);
|
||||
}
|
||||
|
||||
template<
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_write(boost::asio::const_buffer buffer, std::uint8_t& seqnum, CompletionToken&& token)
|
||||
{
|
||||
return writer_.async_write(stream_, buffer, seqnum, std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
|
||||
void write(const bytestring& buffer, std::uint8_t& seqnum, error_code& code)
|
||||
{
|
||||
write(boost::asio::buffer(buffer), seqnum, code);
|
||||
}
|
||||
|
||||
template<
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_write(const bytestring& buffer, CompletionToken&& token)
|
||||
{
|
||||
@@ -152,8 +150,8 @@ public:
|
||||
const std::vector<field_view>& shared_fields() const noexcept { return shared_fields_; }
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
#define BOOST_MYSQL_DETAIL_CHANNEL_DISABLEABLE_SSL_STREAM_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
#include <boost/asio/async_result.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
@@ -24,19 +26,18 @@ class disableable_ssl_stream
|
||||
{
|
||||
public:
|
||||
template <class... Args>
|
||||
disableable_ssl_stream(Args&&... args) noexcept :
|
||||
inner_stream_(std::forward<Args>(args)...)
|
||||
disableable_ssl_stream(Args&&... args) noexcept : inner_stream_(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
void reset() noexcept { set_ssl_active(false); } // TODO: do we really need this?
|
||||
void reset() noexcept { set_ssl_active(false); } // TODO: do we really need this?
|
||||
bool ssl_active() const noexcept { return ssl_active_; }
|
||||
void set_ssl_active(bool v) noexcept { ssl_active_ = v; }
|
||||
|
||||
using executor_type = typename Stream::executor_type;
|
||||
using next_layer_type = Stream;
|
||||
using lowest_layer_type = typename Stream::lowest_layer_type;
|
||||
|
||||
|
||||
executor_type get_executor() noexcept { return inner_stream_.get_executor(); }
|
||||
next_layer_type& next_layer() noexcept { return inner_stream_; }
|
||||
const next_layer_type& next_layer() const noexcept { return inner_stream_; }
|
||||
@@ -44,59 +45,43 @@ public:
|
||||
|
||||
void handshake(error_code& ec);
|
||||
|
||||
template<
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_handshake(CompletionToken&& token);
|
||||
|
||||
void shutdown(error_code& ec);
|
||||
|
||||
template<
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_shutdown(CompletionToken&& token);
|
||||
|
||||
template <class MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence&, error_code& ec);
|
||||
|
||||
template<
|
||||
template <
|
||||
class MutableBufferSequence,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code, std::size_t)) CompletionToken
|
||||
>
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code, std::size_t)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, std::size_t))
|
||||
async_read_some(
|
||||
const MutableBufferSequence& buff,
|
||||
CompletionToken&& token
|
||||
);
|
||||
async_read_some(const MutableBufferSequence& buff, CompletionToken&& token);
|
||||
|
||||
template<class ConstBufferSequence>
|
||||
template <class ConstBufferSequence>
|
||||
std::size_t write_some(const ConstBufferSequence&, error_code& ec);
|
||||
|
||||
template<
|
||||
template <
|
||||
class ConstBufferSequence,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code, std::size_t)) CompletionToken
|
||||
>
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code, std::size_t)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, std::size_t))
|
||||
async_write_some(
|
||||
const ConstBufferSequence& buff,
|
||||
CompletionToken&& token
|
||||
);
|
||||
async_write_some(const ConstBufferSequence& buff, CompletionToken&& token);
|
||||
|
||||
private:
|
||||
Stream inner_stream_;
|
||||
bool ssl_active_ {false};
|
||||
bool ssl_active_{false};
|
||||
};
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/channel/impl/disableable_ssl_stream.hpp>
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_AUXILIAR_STATIC_STRING_HPP_ */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
|
||||
#include <boost/mysql/detail/channel/disableable_ssl_stream.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/compose.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/ssl/stream_base.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
@@ -26,7 +28,6 @@ namespace detail {
|
||||
template <class Stream>
|
||||
using is_ssl_stream = std::is_base_of<boost::asio::ssl::stream_base, Stream>;
|
||||
|
||||
|
||||
// Helpers to get the first non-SSL stream. We can't call just next_layer()
|
||||
// because raw TCP sockets don't support this function. For non-SSL connections,
|
||||
// we just return the stream itself
|
||||
@@ -54,7 +55,8 @@ struct get_non_ssl_stream_t<false>
|
||||
};
|
||||
|
||||
template <typename Stream>
|
||||
auto get_non_ssl_stream(Stream& s) -> decltype(get_non_ssl_stream_t<is_ssl_stream<Stream>::value>::call(s))
|
||||
auto get_non_ssl_stream(Stream& s)
|
||||
-> decltype(get_non_ssl_stream_t<is_ssl_stream<Stream>::value>::call(s))
|
||||
{
|
||||
return get_non_ssl_stream_t<is_ssl_stream<Stream>::value>::call(s);
|
||||
}
|
||||
@@ -64,7 +66,7 @@ struct async_compose_noop
|
||||
{
|
||||
async_compose_noop(...) noexcept {}
|
||||
|
||||
template<class... Args>
|
||||
template <class... Args>
|
||||
void operator()(Args&&...)
|
||||
{
|
||||
assert(false);
|
||||
@@ -91,7 +93,7 @@ struct ssl_handshake_helper<Stream, false>
|
||||
{
|
||||
static void call(disableable_ssl_stream<Stream>&, error_code&)
|
||||
{
|
||||
assert(false); // should never be called
|
||||
assert(false); // should never be called
|
||||
}
|
||||
};
|
||||
|
||||
@@ -103,16 +105,10 @@ struct ssl_handshake_op<Stream, true> : boost::asio::coroutine
|
||||
{
|
||||
disableable_ssl_stream<Stream>& stream_;
|
||||
|
||||
ssl_handshake_op(disableable_ssl_stream<Stream>& stream) noexcept :
|
||||
stream_(stream)
|
||||
{
|
||||
}
|
||||
ssl_handshake_op(disableable_ssl_stream<Stream>& stream) noexcept : stream_(stream) {}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code err = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code err = {})
|
||||
{
|
||||
// Error checking
|
||||
if (err)
|
||||
@@ -125,7 +121,7 @@ struct ssl_handshake_op<Stream, true> : boost::asio::coroutine
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
BOOST_ASIO_CORO_YIELD stream_.next_layer().async_handshake(
|
||||
boost::asio::ssl::stream_base::client,
|
||||
boost::asio::ssl::stream_base::client,
|
||||
std::move(self)
|
||||
);
|
||||
stream_.set_ssl_active(true);
|
||||
@@ -135,8 +131,9 @@ struct ssl_handshake_op<Stream, true> : boost::asio::coroutine
|
||||
};
|
||||
|
||||
template <class Stream>
|
||||
struct ssl_handshake_op<Stream, false> : async_compose_noop {};
|
||||
|
||||
struct ssl_handshake_op<Stream, false> : async_compose_noop
|
||||
{
|
||||
};
|
||||
|
||||
// Helpers to implement shutdown
|
||||
template <class Stream, bool supports_ssl>
|
||||
@@ -150,11 +147,9 @@ struct ssl_shutdown_helper<Stream, true>
|
||||
stream.next_layer().shutdown(ec);
|
||||
}
|
||||
|
||||
template<
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken>
|
||||
static BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
call_async(disableable_ssl_stream<Stream>& stream, CompletionToken&& token)
|
||||
call_async(disableable_ssl_stream<Stream>& stream, CompletionToken&& token)
|
||||
{
|
||||
return stream.next_layer().async_shutdown(std::forward<CompletionToken>(token));
|
||||
}
|
||||
@@ -165,14 +160,12 @@ struct ssl_shutdown_helper<Stream, false>
|
||||
{
|
||||
static void call_sync(disableable_ssl_stream<Stream>&, error_code&)
|
||||
{
|
||||
assert(false); // should never be called
|
||||
assert(false); // should never be called
|
||||
}
|
||||
|
||||
template<
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken
|
||||
>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken>
|
||||
static BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
call_async(disableable_ssl_stream<Stream>& stream, CompletionToken&& token)
|
||||
call_async(disableable_ssl_stream<Stream>& stream, CompletionToken&& token)
|
||||
{
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code)>(
|
||||
async_compose_noop(),
|
||||
@@ -182,33 +175,22 @@ struct ssl_shutdown_helper<Stream, false>
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::detail::disableable_ssl_stream<Stream>::handshake(
|
||||
error_code& ec
|
||||
)
|
||||
void boost::mysql::detail::disableable_ssl_stream<Stream>::handshake(error_code& ec)
|
||||
{
|
||||
ssl_handshake_helper<Stream, is_ssl_stream<Stream>::value>::call(*this, ec);
|
||||
}
|
||||
|
||||
template<class Stream>
|
||||
template<
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code)) CompletionToken
|
||||
>
|
||||
template <class Stream>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::detail::disableable_ssl_stream<Stream>::async_handshake(
|
||||
CompletionToken&& token
|
||||
)
|
||||
boost::mysql::detail::disableable_ssl_stream<Stream>::async_handshake(CompletionToken&& token)
|
||||
{
|
||||
return boost::asio::async_compose<
|
||||
CompletionToken,
|
||||
void(error_code)
|
||||
>(
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code)>(
|
||||
ssl_handshake_op<Stream, is_ssl_stream<Stream>::value>(*this),
|
||||
token,
|
||||
*this
|
||||
@@ -216,21 +198,15 @@ boost::mysql::detail::disableable_ssl_stream<Stream>::async_handshake(
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::detail::disableable_ssl_stream<Stream>::shutdown(
|
||||
error_code& ec
|
||||
)
|
||||
void boost::mysql::detail::disableable_ssl_stream<Stream>::shutdown(error_code& ec)
|
||||
{
|
||||
ssl_shutdown_helper<Stream, is_ssl_stream<Stream>::value>::call_sync(*this, ec);
|
||||
}
|
||||
|
||||
template<class Stream>
|
||||
template<
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code)) CompletionToken
|
||||
>
|
||||
template <class Stream>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::detail::disableable_ssl_stream<Stream>::async_shutdown(
|
||||
CompletionToken&& token
|
||||
)
|
||||
boost::mysql::detail::disableable_ssl_stream<Stream>::async_shutdown(CompletionToken&& token)
|
||||
{
|
||||
return ssl_shutdown_helper<Stream, is_ssl_stream<Stream>::value>::call_async(
|
||||
*this,
|
||||
@@ -238,7 +214,6 @@ boost::mysql::detail::disableable_ssl_stream<Stream>::async_shutdown(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template <class Stream>
|
||||
template <class MutableBufferSequence>
|
||||
std::size_t boost::mysql::detail::disableable_ssl_stream<Stream>::read_some(
|
||||
@@ -256,12 +231,10 @@ std::size_t boost::mysql::detail::disableable_ssl_stream<Stream>::read_some(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Stream>
|
||||
template<
|
||||
template <class Stream>
|
||||
template <
|
||||
class MutableBufferSequence,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code, std::size_t)) CompletionToken
|
||||
>
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code, std::size_t)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code, std::size_t))
|
||||
boost::mysql::detail::disableable_ssl_stream<Stream>::async_read_some(
|
||||
const MutableBufferSequence& buff,
|
||||
@@ -274,11 +247,11 @@ boost::mysql::detail::disableable_ssl_stream<Stream>::async_read_some(
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_non_ssl_stream(inner_stream_).async_read_some(buff, std::forward<CompletionToken>(token));
|
||||
return get_non_ssl_stream(inner_stream_)
|
||||
.async_read_some(buff, std::forward<CompletionToken>(token));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Stream>
|
||||
template <class ConstBufferSequence>
|
||||
std::size_t boost::mysql::detail::disableable_ssl_stream<Stream>::write_some(
|
||||
@@ -296,12 +269,10 @@ std::size_t boost::mysql::detail::disableable_ssl_stream<Stream>::write_some(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Stream>
|
||||
template<
|
||||
template <class Stream>
|
||||
template <
|
||||
class ConstBufferSequence,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code, std::size_t)) CompletionToken
|
||||
>
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code, std::size_t)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code, std::size_t))
|
||||
boost::mysql::detail::disableable_ssl_stream<Stream>::async_write_some(
|
||||
const ConstBufferSequence& buff,
|
||||
@@ -314,9 +285,9 @@ boost::mysql::detail::disableable_ssl_stream<Stream>::async_write_some(
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_non_ssl_stream(inner_stream_).async_write_some(buff, std::forward<CompletionToken>(token));
|
||||
return get_non_ssl_stream(inner_stream_)
|
||||
.async_write_some(buff, std::forward<CompletionToken>(token));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,18 +11,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/channel/message_parser.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
#include <boost/mysql/detail/protocol/common_messages.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
#include <boost/mysql/detail/protocol/deserialization_context.hpp>
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
inline void boost::mysql::detail::message_parser::parse_message(
|
||||
read_buffer& buff,
|
||||
result& res
|
||||
) noexcept
|
||||
inline void
|
||||
boost::mysql::detail::message_parser::parse_message(read_buffer& buff, result& res) noexcept
|
||||
{
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (state_.reading_header)
|
||||
@@ -39,9 +38,9 @@ inline void boost::mysql::detail::message_parser::parse_message(
|
||||
|
||||
// Deserialize the header
|
||||
packet_header header;
|
||||
deserialization_context ctx (
|
||||
deserialization_context ctx(
|
||||
boost::asio::buffer(buff.pending_first() - HEADER_SIZE, HEADER_SIZE),
|
||||
capabilities(0) // unaffected by capabilities
|
||||
capabilities(0) // unaffected by capabilities
|
||||
);
|
||||
errc err = deserialize(ctx, header);
|
||||
boost::ignore_unused(err);
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/channel/message_reader.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/valgrind.hpp>
|
||||
#include <boost/mysql/detail/channel/message_reader.hpp>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/compose.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
|
||||
boost::asio::const_buffer boost::mysql::detail::message_reader::get_next_message(
|
||||
std::uint8_t& seqnum,
|
||||
error_code& ec
|
||||
@@ -30,7 +30,10 @@ boost::asio::const_buffer boost::mysql::detail::message_reader::get_next_message
|
||||
return {};
|
||||
}
|
||||
seqnum = result_.message.seqnum_last + 1;
|
||||
boost::asio::const_buffer res (buffer_.current_message_first() - result_.message.size, result_.message.size);
|
||||
boost::asio::const_buffer res(
|
||||
buffer_.current_message_first() - result_.message.size,
|
||||
result_.message.size
|
||||
);
|
||||
parse_message();
|
||||
return res;
|
||||
}
|
||||
@@ -45,7 +48,7 @@ void boost::mysql::detail::message_reader::read_some(
|
||||
// If we already have a message, complete immediately
|
||||
if (has_message())
|
||||
return;
|
||||
|
||||
|
||||
// Remove processed messages if we can
|
||||
if (!keep_messages)
|
||||
buffer_.remove_reserved();
|
||||
@@ -58,7 +61,8 @@ void boost::mysql::detail::message_reader::read_some(
|
||||
|
||||
// Actually read bytes
|
||||
std::size_t bytes_read = stream.read_some(buffer_.free_area(), ec);
|
||||
if (ec) break;
|
||||
if (ec)
|
||||
break;
|
||||
valgrind_make_mem_defined(buffer_.free_first(), bytes_read);
|
||||
|
||||
// Process them
|
||||
@@ -73,15 +77,13 @@ struct boost::mysql::detail::message_reader::read_some_op : boost::asio::corouti
|
||||
bool keep_messages_;
|
||||
Stream& stream_;
|
||||
|
||||
read_some_op(message_reader& reader, bool keep_messages, Stream& stream) noexcept :
|
||||
reader_(reader), keep_messages_(keep_messages), stream_(stream) {}
|
||||
read_some_op(message_reader& reader, bool keep_messages, Stream& stream) noexcept
|
||||
: reader_(reader), keep_messages_(keep_messages), stream_(stream)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code ec = {},
|
||||
std::size_t bytes_read = 0
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code ec = {}, std::size_t bytes_read = 0)
|
||||
{
|
||||
// Error handling
|
||||
if (ec)
|
||||
@@ -90,7 +92,6 @@ struct boost::mysql::detail::message_reader::read_some_op : boost::asio::corouti
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Non-error path
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
@@ -115,7 +116,7 @@ struct boost::mysql::detail::message_reader::read_some_op : boost::asio::corouti
|
||||
// Actually read bytes
|
||||
BOOST_ASIO_CORO_YIELD stream_.async_read_some(
|
||||
reader_.buffer_.free_area(),
|
||||
std::move(self)
|
||||
std::move(self)
|
||||
);
|
||||
valgrind_make_mem_defined(reader_.buffer_.free_first(), bytes_read);
|
||||
|
||||
@@ -128,10 +129,9 @@ struct boost::mysql::detail::message_reader::read_some_op : boost::asio::corouti
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
template <
|
||||
class Stream,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code)) CompletionToken
|
||||
>
|
||||
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::detail::message_reader::async_read_some(
|
||||
Stream& stream,
|
||||
@@ -161,34 +161,21 @@ boost::asio::const_buffer boost::mysql::detail::message_reader::read_one(
|
||||
return get_next_message(seqnum, ec);
|
||||
}
|
||||
|
||||
|
||||
template<class Stream>
|
||||
struct boost::mysql::detail::message_reader::read_one_op
|
||||
: boost::asio::coroutine
|
||||
template <class Stream>
|
||||
struct boost::mysql::detail::message_reader::read_one_op : boost::asio::coroutine
|
||||
{
|
||||
message_reader& reader_;
|
||||
bool keep_messages_;
|
||||
Stream& stream_;
|
||||
std::uint8_t& seqnum_;
|
||||
|
||||
read_one_op(
|
||||
message_reader& reader,
|
||||
bool keep_messages,
|
||||
Stream& stream,
|
||||
std::uint8_t& seqnum
|
||||
) :
|
||||
reader_(reader),
|
||||
keep_messages_(keep_messages),
|
||||
stream_(stream),
|
||||
seqnum_(seqnum)
|
||||
read_one_op(message_reader& reader, bool keep_messages, Stream& stream, std::uint8_t& seqnum)
|
||||
: reader_(reader), keep_messages_(keep_messages), stream_(stream), seqnum_(seqnum)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code code = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code code = {})
|
||||
{
|
||||
// Error handling
|
||||
if (code)
|
||||
@@ -208,10 +195,10 @@ struct boost::mysql::detail::message_reader::read_one_op
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
template <
|
||||
class Stream,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code, boost::asio::const_buffer)) CompletionToken
|
||||
>
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code, boost::asio::const_buffer))
|
||||
CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code, ::boost::asio::const_buffer)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/channel/message_writer.hpp>
|
||||
|
||||
#include <boost/asio/compose.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
|
||||
@@ -33,25 +34,19 @@ void boost::mysql::detail::message_writer::write(
|
||||
} while (!processor_.is_complete());
|
||||
}
|
||||
|
||||
|
||||
template <class Stream>
|
||||
struct boost::mysql::detail::message_writer::write_op : boost::asio::coroutine
|
||||
{
|
||||
Stream& stream_;
|
||||
message_writer_processor& processor_;
|
||||
|
||||
write_op(Stream& stream, message_writer_processor& processor) noexcept :
|
||||
stream_(stream),
|
||||
processor_(processor)
|
||||
write_op(Stream& stream, message_writer_processor& processor) noexcept
|
||||
: stream_(stream), processor_(processor)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code ec = {},
|
||||
std::size_t = 0
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code ec = {}, std::size_t = 0)
|
||||
{
|
||||
// Error handling
|
||||
if (ec)
|
||||
@@ -60,7 +55,6 @@ struct boost::mysql::detail::message_writer::write_op : boost::asio::coroutine
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Non-error path
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
@@ -81,10 +75,9 @@ struct boost::mysql::detail::message_writer::write_op : boost::asio::coroutine
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
template <
|
||||
class Stream,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(boost::mysql::error_code)) CompletionToken
|
||||
>
|
||||
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::detail::message_writer::async_write(
|
||||
Stream& stream,
|
||||
@@ -101,5 +94,4 @@ boost::mysql::detail::message_writer::async_write(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,52 +11,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/channel/read_buffer.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
boost::mysql::detail::read_buffer::read_buffer(
|
||||
std::size_t size
|
||||
) :
|
||||
buffer_(size, std::uint8_t(0))
|
||||
boost::mysql::detail::read_buffer::read_buffer(std::size_t size) : buffer_(size, std::uint8_t(0))
|
||||
{
|
||||
buffer_.resize(buffer_.capacity());
|
||||
}
|
||||
|
||||
void boost::mysql::detail::read_buffer::move_to_reserved(
|
||||
std::size_t length
|
||||
) noexcept
|
||||
void boost::mysql::detail::read_buffer::move_to_reserved(std::size_t length) noexcept
|
||||
{
|
||||
assert(length <= current_message_size());
|
||||
current_message_offset_ += length;
|
||||
}
|
||||
|
||||
void boost::mysql::detail::read_buffer::remove_current_message_last(
|
||||
std::size_t length
|
||||
) noexcept
|
||||
void boost::mysql::detail::read_buffer::remove_current_message_last(std::size_t length) noexcept
|
||||
{
|
||||
assert(length <= current_message_size());
|
||||
assert(length > 0);
|
||||
std::memmove(
|
||||
pending_first() - length,
|
||||
pending_first(),
|
||||
pending_size()
|
||||
);
|
||||
std::memmove(pending_first() - length, pending_first(), pending_size());
|
||||
pending_offset_ -= length;
|
||||
free_offset_ -= length;
|
||||
}
|
||||
|
||||
void boost::mysql::detail::read_buffer::move_to_current_message(
|
||||
std::size_t n
|
||||
) noexcept
|
||||
void boost::mysql::detail::read_buffer::move_to_current_message(std::size_t n) noexcept
|
||||
{
|
||||
assert(n <= pending_size());
|
||||
pending_offset_ += n;
|
||||
}
|
||||
|
||||
void boost::mysql::detail::read_buffer::move_to_pending(
|
||||
std::size_t n
|
||||
) noexcept
|
||||
void boost::mysql::detail::read_buffer::move_to_pending(std::size_t n) noexcept
|
||||
{
|
||||
assert(n <= free_size());
|
||||
free_offset_ += n;
|
||||
@@ -68,11 +53,7 @@ void boost::mysql::detail::read_buffer::remove_reserved() noexcept
|
||||
{
|
||||
std::size_t currmsg_size = current_message_size();
|
||||
std::size_t pend_size = pending_size();
|
||||
std::memmove(
|
||||
buffer_.data(),
|
||||
current_message_first(),
|
||||
currmsg_size + pend_size
|
||||
);
|
||||
std::memmove(buffer_.data(), current_message_first(), currmsg_size + pend_size);
|
||||
current_message_offset_ = 0;
|
||||
pending_offset_ = currmsg_size;
|
||||
free_offset_ = currmsg_size + pend_size;
|
||||
@@ -88,5 +69,4 @@ void boost::mysql::detail::read_buffer::grow_to_fit(std::size_t n)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,43 +8,46 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_CHANNEL_MESSAGE_PARSER_HPP
|
||||
#define BOOST_MYSQL_DETAIL_CHANNEL_MESSAGE_PARSER_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <boost/mysql/detail/channel/read_buffer.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
|
||||
class message_parser
|
||||
{
|
||||
struct state_t
|
||||
{
|
||||
bool is_first_frame {true};
|
||||
std::uint8_t seqnum_first {};
|
||||
std::uint8_t seqnum_last {};
|
||||
bool reading_header {true};
|
||||
std::size_t remaining_bytes {0};
|
||||
bool more_frames_follow {false};
|
||||
bool has_seqnum_mismatch {false};
|
||||
bool is_first_frame{true};
|
||||
std::uint8_t seqnum_first{};
|
||||
std::uint8_t seqnum_last{};
|
||||
bool reading_header{true};
|
||||
std::size_t remaining_bytes{0};
|
||||
bool more_frames_follow{false};
|
||||
bool has_seqnum_mismatch{false};
|
||||
};
|
||||
|
||||
std::size_t max_frame_size_;
|
||||
state_t state_;
|
||||
|
||||
public:
|
||||
struct result
|
||||
{
|
||||
bool has_message {false}; // whether it has a message or not
|
||||
std::size_t required_size {0}; // if !has_message, number of bytes required to parse the current message
|
||||
bool has_message{false}; // whether it has a message or not
|
||||
std::size_t required_size{
|
||||
0}; // if !has_message, number of bytes required to parse the current message
|
||||
struct message_t
|
||||
{
|
||||
std::uint8_t seqnum_first;
|
||||
std::uint8_t seqnum_last;
|
||||
std::size_t size;
|
||||
bool has_seqnum_mismatch; // for multi-frame messages, set to true if an error mismatch happened
|
||||
} message {}; // if has_message, the actual parsed message
|
||||
bool has_seqnum_mismatch; // for multi-frame messages, set to true if an error mismatch
|
||||
// happened
|
||||
} message{}; // if has_message, the actual parsed message
|
||||
|
||||
void set_required_size(std::size_t size) noexcept
|
||||
{
|
||||
@@ -60,7 +63,8 @@ public:
|
||||
};
|
||||
|
||||
// max_frame_size is configurable so tests run faster
|
||||
message_parser(std::size_t max_frame_size = MAX_PACKET_SIZE) noexcept : max_frame_size_(max_frame_size) {};
|
||||
message_parser(std::size_t max_frame_size = MAX_PACKET_SIZE) noexcept
|
||||
: max_frame_size_(max_frame_size){};
|
||||
|
||||
// Attempts to process a message from buff and puts it into msg.
|
||||
// If a message is read, returns true, and msg.message_first and msg.message_last
|
||||
@@ -71,11 +75,9 @@ public:
|
||||
inline void parse_message(read_buffer& buff, result& res) noexcept;
|
||||
};
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/channel/impl/message_parser.ipp>
|
||||
|
||||
|
||||
@@ -8,16 +8,17 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_CHANNEL_MESSAGE_READER_HPP
|
||||
#define BOOST_MYSQL_DETAIL_CHANNEL_MESSAGE_READER_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/detail/channel/read_buffer.hpp>
|
||||
#include <boost/mysql/detail/channel/message_parser.hpp>
|
||||
#include <boost/mysql/detail/channel/read_buffer.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
#include <boost/asio/async_result.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
@@ -25,13 +26,16 @@ namespace detail {
|
||||
class message_reader
|
||||
{
|
||||
public:
|
||||
message_reader(std::size_t initial_buffer_size, std::size_t max_frame_size = MAX_PACKET_SIZE)
|
||||
: buffer_(initial_buffer_size), parser_(max_frame_size) {}
|
||||
message_reader(std::size_t initial_buffer_size, std::size_t max_frame_size = MAX_PACKET_SIZE)
|
||||
: buffer_(initial_buffer_size), parser_(max_frame_size)
|
||||
{
|
||||
}
|
||||
|
||||
bool has_message() const noexcept { return result_.has_message; }
|
||||
const std::uint8_t* buffer_first() const noexcept { return buffer_.first(); }
|
||||
|
||||
inline boost::asio::const_buffer get_next_message(std::uint8_t& seqnum, error_code& ec) noexcept;
|
||||
inline boost::asio::const_buffer
|
||||
get_next_message(std::uint8_t& seqnum, error_code& ec) noexcept;
|
||||
|
||||
// Reads some messages from stream, until there is at least one
|
||||
// or an error happens. On success, has_message() returns true
|
||||
@@ -42,26 +46,19 @@ public:
|
||||
template <class Stream>
|
||||
void read_some(Stream& stream, error_code& ec, bool keep_messages = false);
|
||||
|
||||
template<
|
||||
class Stream,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken
|
||||
>
|
||||
template <class Stream, BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_read_some(Stream& stream, CompletionToken&& token, bool keep_messages = false);
|
||||
|
||||
// Equivalent to read_some + get_next_message
|
||||
template <class Stream>
|
||||
boost::asio::const_buffer read_one(
|
||||
Stream& stream,
|
||||
std::uint8_t& seqnum,
|
||||
error_code& ec,
|
||||
bool keep_messages = false
|
||||
);
|
||||
boost::asio::const_buffer
|
||||
read_one(Stream& stream, std::uint8_t& seqnum, error_code& ec, bool keep_messages = false);
|
||||
|
||||
template<
|
||||
template <
|
||||
class Stream,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code, boost::asio::const_buffer)) CompletionToken
|
||||
>
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code, boost::asio::const_buffer))
|
||||
CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_read_one(
|
||||
Stream& stream,
|
||||
@@ -72,10 +69,12 @@ public:
|
||||
|
||||
// Exposed for the sake of testing
|
||||
read_buffer& buffer() noexcept { return buffer_; }
|
||||
private:
|
||||
|
||||
template <class Stream> struct read_some_op;
|
||||
template <class Stream> struct read_one_op;
|
||||
private:
|
||||
template <class Stream>
|
||||
struct read_some_op;
|
||||
template <class Stream>
|
||||
struct read_one_op;
|
||||
|
||||
read_buffer buffer_;
|
||||
message_parser parser_;
|
||||
@@ -87,15 +86,10 @@ private:
|
||||
inline void on_read_bytes(size_t num_bytes);
|
||||
};
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/channel/impl/message_reader.hpp>
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_AUXILIAR_STATIC_STRING_HPP_ */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,43 +8,42 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_CHANNEL_MESSAGE_WRITER_HPP
|
||||
#define BOOST_MYSQL_DETAIL_CHANNEL_MESSAGE_WRITER_HPP
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
#include <boost/mysql/detail/channel/message_writer_processor.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
|
||||
class message_writer
|
||||
{
|
||||
message_writer_processor processor_;
|
||||
|
||||
template <class Stream> struct write_op;
|
||||
template <class Stream>
|
||||
struct write_op;
|
||||
|
||||
public:
|
||||
message_writer(std::size_t max_frame_size = MAX_PACKET_SIZE) noexcept : processor_(max_frame_size) {}
|
||||
message_writer(std::size_t max_frame_size = MAX_PACKET_SIZE) noexcept
|
||||
: processor_(max_frame_size)
|
||||
{
|
||||
}
|
||||
|
||||
// Writes an entire message to stream; partitions the message into
|
||||
// chunks and adds the required headers
|
||||
template <class Stream>
|
||||
void write(
|
||||
Stream& stream,
|
||||
boost::asio::const_buffer buffer,
|
||||
std::uint8_t& seqnum,
|
||||
error_code& ec
|
||||
);
|
||||
void
|
||||
write(Stream& stream, boost::asio::const_buffer buffer, std::uint8_t& seqnum, error_code& ec);
|
||||
|
||||
template<
|
||||
class Stream,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken
|
||||
>
|
||||
template <class Stream, BOOST_ASIO_COMPLETION_TOKEN_FOR(void(error_code)) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_write(
|
||||
Stream& stream,
|
||||
@@ -54,10 +53,9 @@ public:
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/channel/impl/message_writer.hpp>
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
#include <boost/mysql/detail/protocol/common_messages.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
@@ -19,59 +21,62 @@ namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
|
||||
class message_writer_processor
|
||||
{
|
||||
boost::asio::const_buffer buffer_to_write_;
|
||||
std::uint8_t* seqnum_ {nullptr};
|
||||
std::size_t bytes_written_ {0};
|
||||
std::array<std::uint8_t, HEADER_SIZE> header_buffer_ {};
|
||||
bool send_empty_frame_ {false}; // Should we send a last, empty frame? (for empty messages or messages of max_frame_size_)
|
||||
std::uint8_t* seqnum_{nullptr};
|
||||
std::size_t bytes_written_{0};
|
||||
std::array<std::uint8_t, HEADER_SIZE> header_buffer_{};
|
||||
bool send_empty_frame_{false}; // Should we send a last, empty frame? (for empty messages or
|
||||
// messages of max_frame_size_)
|
||||
std::size_t max_frame_size_;
|
||||
|
||||
inline std::uint32_t compute_size_to_write() const
|
||||
{
|
||||
return static_cast<std::uint32_t>(std::min(
|
||||
max_frame_size_,
|
||||
buffer_to_write_.size() - bytes_written_
|
||||
));
|
||||
return static_cast<std::uint32_t>(
|
||||
std::min(max_frame_size_, buffer_to_write_.size() - bytes_written_)
|
||||
);
|
||||
}
|
||||
|
||||
inline void process_header_write(
|
||||
std::uint32_t size_to_write,
|
||||
std::uint8_t seqnum
|
||||
)
|
||||
inline void process_header_write(std::uint32_t size_to_write, std::uint8_t seqnum)
|
||||
{
|
||||
packet_header header;
|
||||
header.packet_size.value = size_to_write;
|
||||
header.sequence_number = seqnum;
|
||||
serialization_context ctx (capabilities(0), header_buffer_.data()); // capabilities not relevant here
|
||||
serialization_context ctx(
|
||||
capabilities(0),
|
||||
header_buffer_.data()
|
||||
); // capabilities not relevant here
|
||||
serialize(ctx, header);
|
||||
}
|
||||
|
||||
public:
|
||||
// We write two buffers at once: the header and the body part
|
||||
using buffers_type = std::array<boost::asio::const_buffer, 2>;
|
||||
|
||||
message_writer_processor(std::size_t max_frame_size = MAX_PACKET_SIZE) noexcept :
|
||||
max_frame_size_(max_frame_size) {}
|
||||
|
||||
message_writer_processor(std::size_t max_frame_size = MAX_PACKET_SIZE) noexcept
|
||||
: max_frame_size_(max_frame_size)
|
||||
{
|
||||
}
|
||||
|
||||
void reset(boost::asio::const_buffer buffer, std::uint8_t& seqnum)
|
||||
{
|
||||
buffer_to_write_ = buffer;
|
||||
seqnum_ = &seqnum;
|
||||
bytes_written_ = 0;
|
||||
send_empty_frame_ = (buffer.size() == 0); // If the packet is empty, we should just send the header
|
||||
send_empty_frame_ =
|
||||
(buffer.size() == 0); // If the packet is empty, we should just send the header
|
||||
}
|
||||
|
||||
|
||||
buffers_type prepare_next_chunk() noexcept
|
||||
{
|
||||
auto first = static_cast<const std::uint8_t*>(buffer_to_write_.data());
|
||||
std::size_t size_to_write = compute_size_to_write();
|
||||
process_header_write(size_to_write, (*seqnum_)++);
|
||||
return {{
|
||||
boost::asio::buffer(header_buffer_),
|
||||
boost::asio::buffer(first + bytes_written_, size_to_write)
|
||||
}};
|
||||
return {
|
||||
{boost::asio::buffer(header_buffer_),
|
||||
boost::asio::buffer(first + bytes_written_, size_to_write)}
|
||||
};
|
||||
}
|
||||
|
||||
void on_bytes_written() noexcept
|
||||
@@ -80,14 +85,18 @@ public:
|
||||
bytes_written_ += new_bytes;
|
||||
// If we sent all the bytes, but the last frame was just max_frame_size_ bytes, the protocol
|
||||
// requires us to send a last, empty frame
|
||||
send_empty_frame_ = (new_bytes == max_frame_size_ && bytes_written_ == buffer_to_write_.size());
|
||||
send_empty_frame_ =
|
||||
(new_bytes == max_frame_size_ && bytes_written_ == buffer_to_write_.size());
|
||||
}
|
||||
|
||||
bool is_complete() const noexcept { return !send_empty_frame_ && bytes_written_ >= buffer_to_write_.size(); }
|
||||
bool is_complete() const noexcept
|
||||
{
|
||||
return !send_empty_frame_ && bytes_written_ >= buffer_to_write_.size();
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,17 +8,17 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_CHANNEL_READ_BUFFER_HPP
|
||||
#define BOOST_MYSQL_DETAIL_CHANNEL_READ_BUFFER_HPP
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
|
||||
// Custom buffer type optimized for read operations performed in the MySQL protocol.
|
||||
// The buffer is a single, resizable chunk of memory with four areas:
|
||||
// - Reserved area: messages that have already been read but are kept alive,
|
||||
@@ -29,9 +29,10 @@ namespace detail {
|
||||
class read_buffer
|
||||
{
|
||||
bytestring buffer_;
|
||||
std::size_t current_message_offset_ {0};
|
||||
std::size_t pending_offset_ {0};
|
||||
std::size_t free_offset_ {0};
|
||||
std::size_t current_message_offset_{0};
|
||||
std::size_t pending_offset_{0};
|
||||
std::size_t free_offset_{0};
|
||||
|
||||
public:
|
||||
inline read_buffer(std::size_t size);
|
||||
|
||||
@@ -42,22 +43,43 @@ public:
|
||||
// Area accessors
|
||||
std::uint8_t* reserved_first() noexcept { return buffer_.data(); }
|
||||
const std::uint8_t* reserved_first() const noexcept { return buffer_.data(); }
|
||||
std::uint8_t* current_message_first() noexcept { return buffer_.data() + current_message_offset_; }
|
||||
const std::uint8_t* current_message_first() const noexcept { return buffer_.data() + current_message_offset_; }
|
||||
std::uint8_t* current_message_first() noexcept
|
||||
{
|
||||
return buffer_.data() + current_message_offset_;
|
||||
}
|
||||
const std::uint8_t* current_message_first() const noexcept
|
||||
{
|
||||
return buffer_.data() + current_message_offset_;
|
||||
}
|
||||
std::uint8_t* pending_first() noexcept { return buffer_.data() + pending_offset_; }
|
||||
const std::uint8_t* pending_first() const noexcept { return buffer_.data() + pending_offset_; }
|
||||
std::uint8_t* free_first() noexcept { return buffer_.data() + free_offset_; }
|
||||
const std::uint8_t* free_first() const noexcept { return buffer_.data() + free_offset_; }
|
||||
|
||||
std::size_t reserved_size() const noexcept { return current_message_offset_; }
|
||||
std::size_t current_message_size() const noexcept { return pending_offset_ - current_message_offset_; }
|
||||
std::size_t current_message_size() const noexcept
|
||||
{
|
||||
return pending_offset_ - current_message_offset_;
|
||||
}
|
||||
std::size_t pending_size() const noexcept { return free_offset_ - pending_offset_; }
|
||||
std::size_t free_size() const noexcept { return buffer_.size() - free_offset_; }
|
||||
|
||||
boost::asio::const_buffer reserved_area() const noexcept { return boost::asio::buffer(reserved_first(), reserved_size()); }
|
||||
boost::asio::const_buffer current_message() const noexcept { return boost::asio::buffer(current_message_first(), current_message_size()); }
|
||||
boost::asio::const_buffer pending_area() const noexcept { return boost::asio::buffer(pending_first(), pending_size()); }
|
||||
boost::asio::mutable_buffer free_area() noexcept { return boost::asio::buffer(free_first(), free_size()); }
|
||||
boost::asio::const_buffer reserved_area() const noexcept
|
||||
{
|
||||
return boost::asio::buffer(reserved_first(), reserved_size());
|
||||
}
|
||||
boost::asio::const_buffer current_message() const noexcept
|
||||
{
|
||||
return boost::asio::buffer(current_message_first(), current_message_size());
|
||||
}
|
||||
boost::asio::const_buffer pending_area() const noexcept
|
||||
{
|
||||
return boost::asio::buffer(pending_first(), pending_size());
|
||||
}
|
||||
boost::asio::mutable_buffer free_area() noexcept
|
||||
{
|
||||
return boost::asio::buffer(free_first(), free_size());
|
||||
}
|
||||
|
||||
// Moves n bytes from the free to the processing area (e.g. they've been read)
|
||||
inline void move_to_pending(std::size_t n) noexcept;
|
||||
@@ -81,17 +103,10 @@ public:
|
||||
inline void grow_to_fit(std::size_t n);
|
||||
};
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/channel/impl/read_buffer.ipp>
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_AUXILIAR_STATIC_STRING_HPP_ */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,34 +8,24 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_CLOSE_CONNECTION_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_CLOSE_CONNECTION_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <class SocketStream>
|
||||
void close_connection(
|
||||
channel<SocketStream>& chan,
|
||||
error_code& code,
|
||||
error_info& info
|
||||
);
|
||||
void close_connection(channel<SocketStream>& chan, error_code& code, error_info& info);
|
||||
|
||||
template <class SocketStream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_close_connection(
|
||||
channel<SocketStream>& chan,
|
||||
CompletionToken&& token,
|
||||
error_info& info
|
||||
);
|
||||
async_close_connection(channel<SocketStream>& chan, CompletionToken&& token, error_info& info);
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/close_connection.hpp>
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_CLOSE_CONNECTION_HPP_ */
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_CLOSE_STATEMENT_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_CLOSE_STATEMENT_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/statement_base.hpp>
|
||||
|
||||
namespace boost {
|
||||
@@ -33,9 +33,9 @@ async_close_statement(
|
||||
error_info& info
|
||||
);
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/close_statement.hpp>
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_CONNECT_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_CONNECT_HPP
|
||||
|
||||
#include <boost/mysql/handshake_params.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/handshake_params.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -35,9 +35,9 @@ async_connect(
|
||||
CompletionToken&& token
|
||||
);
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/connect.hpp>
|
||||
|
||||
|
||||
@@ -8,11 +8,10 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_EXECUTE_GENERIC_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_EXECUTE_GENERIC_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/detail/protocol/resultset_encoding.hpp>
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -39,9 +38,9 @@ async_execute_generic(
|
||||
CompletionToken&& token
|
||||
);
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/execute_generic.hpp>
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_EXECUTE_QUERY_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_EXECUTE_QUERY_HPP
|
||||
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -37,9 +37,9 @@ async_execute_query(
|
||||
CompletionToken&& token
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/execute_query.hpp>
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_EXECUTE_STATEMENT_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_EXECUTE_STATEMENT_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/statement_base.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/execute_params.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/execute_params.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/statement_base.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -39,9 +39,9 @@ async_execute_statement(
|
||||
CompletionToken&& token
|
||||
);
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/execute_statement.hpp>
|
||||
|
||||
|
||||
@@ -8,11 +8,10 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_HANDSHAKE_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_HANDSHAKE_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/handshake_params.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
@@ -34,11 +33,10 @@ async_handshake(
|
||||
CompletionToken&& token
|
||||
);
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/handshake.hpp>
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,30 +12,28 @@
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/close_connection.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/quit_connection.hpp>
|
||||
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template<class SocketStream>
|
||||
template <class SocketStream>
|
||||
struct close_connection_op : boost::asio::coroutine
|
||||
{
|
||||
channel<SocketStream>& chan_;
|
||||
error_info& output_info_;
|
||||
|
||||
close_connection_op(channel<SocketStream>& chan, error_info& output_info) :
|
||||
chan_(chan),
|
||||
output_info_(output_info)
|
||||
close_connection_op(channel<SocketStream>& chan, error_info& output_info)
|
||||
: chan_(chan), output_info_(output_info)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code err = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code err = {})
|
||||
{
|
||||
error_code close_err;
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
@@ -47,11 +45,7 @@ struct close_connection_op : boost::asio::coroutine
|
||||
BOOST_ASIO_CORO_YIELD break;
|
||||
}
|
||||
|
||||
BOOST_ASIO_CORO_YIELD async_quit_connection(
|
||||
chan_,
|
||||
std::move(self),
|
||||
output_info_
|
||||
);
|
||||
BOOST_ASIO_CORO_YIELD async_quit_connection(chan_, std::move(self), output_info_);
|
||||
|
||||
// We call close regardless of the quit outcome
|
||||
close_err = chan_.close();
|
||||
@@ -60,9 +54,9 @@ struct close_connection_op : boost::asio::coroutine
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class SocketStream>
|
||||
void boost::mysql::detail::close_connection(
|
||||
@@ -86,21 +80,18 @@ void boost::mysql::detail::close_connection(
|
||||
}
|
||||
|
||||
template <class SocketStream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::detail::async_close_connection(
|
||||
channel<SocketStream>& chan,
|
||||
CompletionToken&& token,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
return boost::asio::async_compose<
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
>(close_connection_op<SocketStream>{chan, info}, token, chan);
|
||||
return boost::asio::async_compose<CompletionToken, void(boost::mysql::error_code)>(
|
||||
close_connection_op<SocketStream>{chan, info},
|
||||
token,
|
||||
chan
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_CLOSE_CONNECTION_HPP_ */
|
||||
|
||||
@@ -17,26 +17,19 @@ namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template<class Stream>
|
||||
template <class Stream>
|
||||
struct close_statement_op : boost::asio::coroutine
|
||||
{
|
||||
channel<Stream>& chan_;
|
||||
statement_base& stmt_;
|
||||
|
||||
close_statement_op(
|
||||
channel<Stream>& chan,
|
||||
statement_base& stmt
|
||||
) noexcept :
|
||||
chan_(chan),
|
||||
stmt_(stmt)
|
||||
close_statement_op(channel<Stream>& chan, statement_base& stmt) noexcept
|
||||
: chan_(chan), stmt_(stmt)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code err = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code err = {})
|
||||
{
|
||||
// Error checking
|
||||
if (err)
|
||||
@@ -64,20 +57,16 @@ struct close_statement_op : boost::asio::coroutine
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::detail::close_statement(
|
||||
channel<Stream>& chan,
|
||||
statement_base& stmt,
|
||||
error_code& code,
|
||||
error_info&
|
||||
)
|
||||
void boost::mysql::detail::
|
||||
close_statement(channel<Stream>& chan, statement_base& stmt, error_code& code, error_info&)
|
||||
{
|
||||
// Compose the close message
|
||||
com_stmt_close_packet packet {stmt.id()};
|
||||
com_stmt_close_packet packet{stmt.id()};
|
||||
|
||||
// Serialize it
|
||||
serialize_message(packet, chan.current_capabilities(), chan.shared_buffer());
|
||||
@@ -90,19 +79,12 @@ void boost::mysql::detail::close_statement(
|
||||
}
|
||||
|
||||
template <class Stream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
boost::mysql::detail::async_close_statement(
|
||||
channel<Stream>& chan,
|
||||
statement_base& stmt,
|
||||
CompletionToken&& token,
|
||||
error_info&
|
||||
)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::detail::
|
||||
async_close_statement(channel<Stream>& chan, statement_base& stmt, CompletionToken&& token, error_info&)
|
||||
{
|
||||
// Compose the close message
|
||||
com_stmt_close_packet packet {stmt.id()};
|
||||
com_stmt_close_packet packet{stmt.id()};
|
||||
|
||||
// Serialize it
|
||||
serialize_message(packet, chan.current_capabilities(), chan.shared_buffer());
|
||||
@@ -115,5 +97,4 @@ boost::mysql::detail::async_close_statement(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_CLOSE_STATEMENT_HPP_ */
|
||||
|
||||
@@ -32,19 +32,13 @@ struct connect_op : boost::asio::coroutine
|
||||
error_info& output_info,
|
||||
const endpoint_type& ep,
|
||||
const handshake_params& params
|
||||
) :
|
||||
chan_(chan),
|
||||
output_info_(output_info),
|
||||
ep_(ep),
|
||||
params_(params)
|
||||
)
|
||||
: chan_(chan), output_info_(output_info), ep_(ep), params_(params)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code code = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code code = {})
|
||||
{
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
@@ -59,12 +53,7 @@ struct connect_op : boost::asio::coroutine
|
||||
}
|
||||
|
||||
// Handshake
|
||||
BOOST_ASIO_CORO_YIELD async_handshake(
|
||||
chan_,
|
||||
params_,
|
||||
std::move(self),
|
||||
output_info_
|
||||
);
|
||||
BOOST_ASIO_CORO_YIELD async_handshake(chan_, params_, std::move(self), output_info_);
|
||||
if (code)
|
||||
{
|
||||
chan_.close();
|
||||
@@ -74,9 +63,9 @@ struct connect_op : boost::asio::coroutine
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::detail::connect(
|
||||
@@ -102,10 +91,7 @@ void boost::mysql::detail::connect(
|
||||
}
|
||||
|
||||
template <class Stream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::detail::async_connect(
|
||||
channel<Stream>& chan,
|
||||
const typename Stream::lowest_layer_type::endpoint_type& endpoint,
|
||||
@@ -115,7 +101,10 @@ boost::mysql::detail::async_connect(
|
||||
)
|
||||
{
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code)>(
|
||||
connect_op<Stream>{chan, info, endpoint, params}, token, chan);
|
||||
connect_op<Stream>{chan, info, endpoint, params},
|
||||
token,
|
||||
chan
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_CONNECT_HPP_ */
|
||||
|
||||
@@ -10,14 +10,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/execute_generic.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/execute_generic.hpp>
|
||||
#include <boost/mysql/detail/protocol/capabilities.hpp>
|
||||
#include <boost/mysql/detail/protocol/common_messages.hpp>
|
||||
#include <boost/mysql/detail/protocol/resultset_encoding.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
@@ -32,21 +34,17 @@ class execute_processor
|
||||
error_info& output_info_;
|
||||
bytestring& write_buffer_;
|
||||
capabilities caps_;
|
||||
std::size_t num_fields_ {};
|
||||
std::size_t remaining_fields_ {};
|
||||
std::size_t num_fields_{};
|
||||
std::size_t remaining_fields_{};
|
||||
|
||||
public:
|
||||
execute_processor(
|
||||
resultset_base& output,
|
||||
error_info& output_info,
|
||||
bytestring& write_buffer,
|
||||
capabilities caps
|
||||
) noexcept:
|
||||
output_(output),
|
||||
output_info_(output_info),
|
||||
write_buffer_(write_buffer),
|
||||
caps_(caps)
|
||||
{
|
||||
};
|
||||
) noexcept
|
||||
: output_(output), output_info_(output_info), write_buffer_(write_buffer), caps_(caps){};
|
||||
|
||||
template <class Serializable, class Stream>
|
||||
void process_request(
|
||||
@@ -59,15 +57,12 @@ public:
|
||||
serialize_message(request, caps_, write_buffer_);
|
||||
}
|
||||
|
||||
void process_response(
|
||||
boost::asio::const_buffer response,
|
||||
error_code& err
|
||||
)
|
||||
void process_response(boost::asio::const_buffer response, error_code& err)
|
||||
{
|
||||
// Response may be: ok_packet, err_packet, local infile request (not implemented)
|
||||
// If it is none of this, then the message type itself is the beginning of
|
||||
// a length-encoded int containing the field count
|
||||
deserialization_context ctx (response, caps_);
|
||||
deserialization_context ctx(response, caps_);
|
||||
std::uint8_t msg_type = 0;
|
||||
err = make_error_code(deserialize(ctx, msg_type));
|
||||
if (err)
|
||||
@@ -113,7 +108,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
remaining_fields_ = num_fields_;
|
||||
remaining_fields_ = num_fields_;
|
||||
output_.prepare_meta(num_fields_);
|
||||
}
|
||||
}
|
||||
@@ -121,7 +116,7 @@ public:
|
||||
error_code process_field_definition(boost::asio::const_buffer message)
|
||||
{
|
||||
column_definition_packet field_definition;
|
||||
deserialization_context ctx (message, caps_);
|
||||
deserialization_context ctx(message, caps_);
|
||||
auto err = deserialize_message(ctx, field_definition);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -137,27 +132,19 @@ public:
|
||||
bool has_remaining_fields() const noexcept { return remaining_fields_ != 0; }
|
||||
};
|
||||
|
||||
template<class Stream>
|
||||
template <class Stream>
|
||||
struct execute_generic_op : boost::asio::coroutine
|
||||
{
|
||||
channel<Stream>& chan_;
|
||||
execute_processor processor_;
|
||||
|
||||
execute_generic_op(
|
||||
channel<Stream>& chan,
|
||||
const execute_processor& processor
|
||||
) :
|
||||
chan_(chan),
|
||||
processor_(processor)
|
||||
execute_generic_op(channel<Stream>& chan, const execute_processor& processor)
|
||||
: chan_(chan), processor_(processor)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code err = {},
|
||||
boost::asio::const_buffer read_message = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code err = {}, boost::asio::const_buffer read_message = {})
|
||||
{
|
||||
// Error checking
|
||||
if (err)
|
||||
@@ -170,10 +157,14 @@ struct execute_generic_op : boost::asio::coroutine
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
// The request message has already been composed in the initiating fn. Send it
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_write(chan_.shared_buffer(), processor_.sequence_number(), std::move(self));
|
||||
BOOST_ASIO_CORO_YIELD chan_
|
||||
.async_write(chan_.shared_buffer(), processor_.sequence_number(), std::move(self));
|
||||
|
||||
// Read the response
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_read_one(processor_.sequence_number(), std::move(self));
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_read_one(
|
||||
processor_.sequence_number(),
|
||||
std::move(self)
|
||||
);
|
||||
|
||||
// Response may be: ok_packet, err_packet, local infile request
|
||||
// (not implemented), or response with fields
|
||||
@@ -216,9 +207,9 @@ struct execute_generic_op : boost::asio::coroutine
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class Stream, class Serializable>
|
||||
void boost::mysql::detail::execute_generic(
|
||||
@@ -231,12 +222,8 @@ void boost::mysql::detail::execute_generic(
|
||||
)
|
||||
{
|
||||
// Compose a com_query message, reset seq num
|
||||
execute_processor processor (
|
||||
output,
|
||||
info,
|
||||
channel.shared_buffer(),
|
||||
channel.current_capabilities()
|
||||
);
|
||||
execute_processor
|
||||
processor(output, info, channel.shared_buffer(), channel.current_capabilities());
|
||||
processor.process_request(request, encoding, channel);
|
||||
|
||||
// Send it
|
||||
@@ -249,7 +236,8 @@ void boost::mysql::detail::execute_generic(
|
||||
if (err)
|
||||
return;
|
||||
|
||||
// Response may be: ok_packet, err_packet, local infile request (not implemented), or response with fields
|
||||
// Response may be: ok_packet, err_packet, local infile request (not implemented), or response
|
||||
// with fields
|
||||
processor.process_response(read_buffer, err);
|
||||
if (err)
|
||||
return;
|
||||
@@ -278,10 +266,7 @@ void boost::mysql::detail::execute_generic(
|
||||
}
|
||||
|
||||
template <class Stream, class Serializable, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::detail::async_execute_generic(
|
||||
resultset_encoding encoding,
|
||||
channel<Stream>& channel,
|
||||
@@ -291,12 +276,8 @@ boost::mysql::detail::async_execute_generic(
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
execute_processor processor (
|
||||
output,
|
||||
info,
|
||||
channel.shared_buffer(),
|
||||
channel.current_capabilities()
|
||||
);
|
||||
execute_processor
|
||||
processor(output, info, channel.shared_buffer(), channel.current_capabilities());
|
||||
processor.process_request(request, encoding, channel);
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code)>(
|
||||
execute_generic_op<Stream>(channel, processor),
|
||||
@@ -305,5 +286,4 @@ boost::mysql::detail::async_execute_generic(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endif /* INCLUDE_MYSQL_IMPL_NETWORK_ALGORITHMS_READ_RESULTSET_HEAD_IPP_ */
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/execute_generic.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/execute_query.hpp>
|
||||
#include <boost/mysql/detail/protocol/query_messages.hpp>
|
||||
#include <boost/mysql/detail/protocol/resultset_encoding.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/execute_generic.hpp>
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::detail::execute_query(
|
||||
@@ -24,23 +24,12 @@ void boost::mysql::detail::execute_query(
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
com_query_packet request { string_eof(query) };
|
||||
execute_generic(
|
||||
resultset_encoding::text,
|
||||
channel,
|
||||
request,
|
||||
output,
|
||||
err,
|
||||
info
|
||||
);
|
||||
com_query_packet request{string_eof(query)};
|
||||
execute_generic(resultset_encoding::text, channel, request, output, err, info);
|
||||
}
|
||||
|
||||
|
||||
template <class Stream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::detail::async_execute_query(
|
||||
channel<Stream>& chan,
|
||||
boost::string_view query,
|
||||
@@ -49,7 +38,7 @@ boost::mysql::detail::async_execute_query(
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
com_query_packet request { string_eof(query) };
|
||||
com_query_packet request{string_eof(query)};
|
||||
return async_execute_generic(
|
||||
resultset_encoding::text,
|
||||
chan,
|
||||
@@ -60,5 +49,4 @@ boost::mysql::detail::async_execute_query(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_EXECUTE_QUERY_HPP_ */
|
||||
|
||||
@@ -10,18 +10,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/execute_statement.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/stringize.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/execute_generic.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/execute_statement.hpp>
|
||||
#include <boost/mysql/detail/protocol/prepared_statement_messages.hpp>
|
||||
#include <boost/mysql/detail/protocol/resultset_encoding.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/stringize.hpp>
|
||||
#include <boost/mysql/statement_base.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/execute_params.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/compose.hpp>
|
||||
#include <boost/mysql/execute_params.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/statement_base.hpp>
|
||||
|
||||
#include <boost/asio/compose.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -33,14 +33,13 @@ com_stmt_execute_packet<FieldViewFwdIterator> make_stmt_execute_packet(
|
||||
const statement_base& stmt
|
||||
)
|
||||
{
|
||||
return com_stmt_execute_packet<FieldViewFwdIterator> {
|
||||
return com_stmt_execute_packet<FieldViewFwdIterator>{
|
||||
stmt.id(),
|
||||
std::uint8_t(0), // flags
|
||||
std::uint32_t(1), // iteration count
|
||||
std::uint8_t(1), // new params flag: set
|
||||
std::uint8_t(0), // flags
|
||||
std::uint32_t(1), // iteration count
|
||||
std::uint8_t(1), // new params flag: set
|
||||
params.first(),
|
||||
params.last()
|
||||
};
|
||||
params.last()};
|
||||
}
|
||||
|
||||
template <class FieldViewFwdIterator>
|
||||
@@ -54,7 +53,10 @@ error_code check_num_params(
|
||||
if (param_count != stmt.num_params())
|
||||
{
|
||||
info.set_message(detail::stringize(
|
||||
"execute statement: expected ", stmt.num_params(), " params, but got ", param_count
|
||||
"execute statement: expected ",
|
||||
stmt.num_params(),
|
||||
" params, but got ",
|
||||
param_count
|
||||
));
|
||||
return make_error_code(errc::wrong_num_params);
|
||||
}
|
||||
@@ -70,7 +72,7 @@ struct fast_fail_op : boost::asio::coroutine
|
||||
|
||||
fast_fail_op(error_code err) noexcept : err_(err) {}
|
||||
|
||||
template<class Self>
|
||||
template <class Self>
|
||||
void operator()(Self& self)
|
||||
{
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
@@ -81,10 +83,9 @@ struct fast_fail_op : boost::asio::coroutine
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class Stream, class FieldViewFwdIterator>
|
||||
void boost::mysql::detail::execute_statement(
|
||||
@@ -111,10 +112,7 @@ void boost::mysql::detail::execute_statement(
|
||||
}
|
||||
|
||||
template <class Stream, class FieldViewFwdIterator, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::detail::async_execute_statement(
|
||||
channel<Stream>& chan,
|
||||
const statement_base& stmt,
|
||||
@@ -143,6 +141,4 @@ boost::mysql::detail::async_execute_statement(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_EXECUTE_STATEMENT_HPP_ */
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/auth/auth_calculator.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/handshake.hpp>
|
||||
#include <boost/mysql/detail/protocol/capabilities.hpp>
|
||||
#include <boost/mysql/detail/protocol/handshake_messages.hpp>
|
||||
#include <boost/mysql/detail/auth/auth_calculator.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -38,7 +39,7 @@ inline error_code deserialize_handshake(
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
deserialization_context ctx (boost::asio::buffer(buffer), capabilities());
|
||||
deserialization_context ctx(boost::asio::buffer(buffer), capabilities());
|
||||
std::uint8_t msg_type = 0;
|
||||
auto err = deserialize(ctx, msg_type);
|
||||
if (err != errc::ok)
|
||||
@@ -81,8 +82,9 @@ class handshake_processor
|
||||
handshake_params params_;
|
||||
capabilities negotiated_caps_;
|
||||
auth_calculator auth_calc_;
|
||||
|
||||
public:
|
||||
handshake_processor(const handshake_params& params): params_(params) {};
|
||||
handshake_processor(const handshake_params& params) : params_(params){};
|
||||
capabilities negotiated_capabilities() const noexcept { return negotiated_caps_; }
|
||||
const handshake_params& params() const noexcept { return params_; }
|
||||
bool use_ssl() const noexcept { return negotiated_caps_.has(CLIENT_SSL); }
|
||||
@@ -91,20 +93,33 @@ public:
|
||||
error_code process_capabilities(const handshake_packet& handshake, bool is_ssl_stream)
|
||||
{
|
||||
auto ssl = params_.ssl();
|
||||
capabilities server_caps (handshake.capability_falgs);
|
||||
capabilities server_caps(handshake.capability_falgs);
|
||||
capabilities required_caps = mandatory_capabilities |
|
||||
conditional_capability(!params_.database().empty(), CLIENT_CONNECT_WITH_DB) |
|
||||
conditional_capability(ssl == ssl_mode::require && is_ssl_stream, CLIENT_SSL);
|
||||
conditional_capability(
|
||||
!params_.database().empty(),
|
||||
CLIENT_CONNECT_WITH_DB
|
||||
) |
|
||||
conditional_capability(
|
||||
ssl == ssl_mode::require && is_ssl_stream,
|
||||
CLIENT_SSL
|
||||
);
|
||||
if (!server_caps.has_all(required_caps))
|
||||
{
|
||||
return make_error_code(errc::server_unsupported);
|
||||
}
|
||||
negotiated_caps_ = server_caps & (required_caps | optional_capabilities |
|
||||
conditional_capability(ssl == ssl_mode::enable && is_ssl_stream, CLIENT_SSL));
|
||||
conditional_capability(
|
||||
ssl == ssl_mode::enable && is_ssl_stream,
|
||||
CLIENT_SSL
|
||||
));
|
||||
return error_code();
|
||||
}
|
||||
|
||||
error_code process_handshake(boost::asio::const_buffer buffer, error_info& info, bool is_ssl_stream)
|
||||
error_code process_handshake(
|
||||
boost::asio::const_buffer buffer,
|
||||
error_info& info,
|
||||
bool is_ssl_stream
|
||||
)
|
||||
{
|
||||
// Deserialize server greeting
|
||||
handshake_packet handshake;
|
||||
@@ -129,12 +144,11 @@ public:
|
||||
// Response to that initial greeting
|
||||
void compose_ssl_request(bytestring& buffer)
|
||||
{
|
||||
ssl_request sslreq {
|
||||
ssl_request sslreq{
|
||||
negotiated_capabilities().get(),
|
||||
static_cast<std::uint32_t>(MAX_PACKET_SIZE),
|
||||
get_collation_first_byte(params_.connection_collation()),
|
||||
{}
|
||||
};
|
||||
{}};
|
||||
|
||||
// Serialize and send
|
||||
serialize_message(sslreq, negotiated_caps_, buffer);
|
||||
@@ -143,15 +157,14 @@ public:
|
||||
void compose_handshake_response(bytestring& buffer)
|
||||
{
|
||||
// Compose response
|
||||
handshake_response_packet response {
|
||||
handshake_response_packet response{
|
||||
negotiated_caps_.get(),
|
||||
static_cast<std::uint32_t>(MAX_PACKET_SIZE),
|
||||
get_collation_first_byte(params_.connection_collation()),
|
||||
string_null(params_.username()),
|
||||
string_lenenc(auth_calc_.response()),
|
||||
string_null(params_.database()),
|
||||
string_null(auth_calc_.plugin_name())
|
||||
};
|
||||
string_null(auth_calc_.plugin_name())};
|
||||
|
||||
// Serialize
|
||||
serialize_message(response, negotiated_caps_, buffer);
|
||||
@@ -165,7 +178,7 @@ public:
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
deserialization_context ctx (server_response, negotiated_caps_);
|
||||
deserialization_context ctx(server_response, negotiated_caps_);
|
||||
std::uint8_t msg_type = 0;
|
||||
auto err = make_error_code(deserialize(ctx, msg_type));
|
||||
if (err)
|
||||
@@ -234,7 +247,7 @@ public:
|
||||
return err;
|
||||
|
||||
serialize_message(
|
||||
auth_switch_response_packet {string_eof(auth_calc_.response())},
|
||||
auth_switch_response_packet{string_eof(auth_calc_.response())},
|
||||
negotiated_caps_,
|
||||
write_buffer
|
||||
);
|
||||
@@ -249,31 +262,21 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class Stream>
|
||||
template <class Stream>
|
||||
struct handshake_op : boost::asio::coroutine
|
||||
{
|
||||
channel<Stream>& chan_;
|
||||
error_info& output_info_;
|
||||
handshake_processor processor_;
|
||||
auth_result auth_state_ {auth_result::invalid};
|
||||
auth_result auth_state_{auth_result::invalid};
|
||||
|
||||
handshake_op(
|
||||
channel<Stream>& channel,
|
||||
error_info& output_info,
|
||||
const handshake_params& params
|
||||
) :
|
||||
chan_(channel),
|
||||
output_info_(output_info),
|
||||
processor_(params)
|
||||
handshake_op(channel<Stream>& channel, error_info& output_info, const handshake_params& params)
|
||||
: chan_(channel), output_info_(output_info), processor_(params)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code err = {},
|
||||
boost::asio::const_buffer read_msg = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code err = {}, boost::asio::const_buffer read_msg = {})
|
||||
{
|
||||
// Error checking
|
||||
if (err)
|
||||
@@ -286,10 +289,14 @@ struct handshake_op : boost::asio::coroutine
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
// Read server greeting
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_read_one(chan_.shared_sequence_number(), std::move(self));
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_read_one(
|
||||
chan_.shared_sequence_number(),
|
||||
std::move(self)
|
||||
);
|
||||
|
||||
// Process server greeting
|
||||
err = processor_.process_handshake(read_msg, output_info_, is_ssl_stream<Stream>::value);
|
||||
err = processor_
|
||||
.process_handshake(read_msg, output_info_, is_ssl_stream<Stream>::value);
|
||||
if (err)
|
||||
{
|
||||
self.complete(err);
|
||||
@@ -315,12 +322,19 @@ struct handshake_op : boost::asio::coroutine
|
||||
|
||||
// Compose and send handshake response
|
||||
processor_.compose_handshake_response(chan_.shared_buffer());
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_write(chan_.shared_buffer(), chan_.shared_sequence_number(), std::move(self));
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_write(
|
||||
chan_.shared_buffer(),
|
||||
chan_.shared_sequence_number(),
|
||||
std::move(self)
|
||||
);
|
||||
|
||||
while (auth_state_ != auth_result::complete)
|
||||
{
|
||||
// Receive response
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_read_one(chan_.shared_sequence_number(), std::move(self));
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_read_one(
|
||||
chan_.shared_sequence_number(),
|
||||
std::move(self)
|
||||
);
|
||||
|
||||
// Process it
|
||||
err = processor_.process_handshake_server_response(
|
||||
@@ -347,9 +361,9 @@ struct handshake_op : boost::asio::coroutine
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::detail::handshake(
|
||||
@@ -362,7 +376,7 @@ void boost::mysql::detail::handshake(
|
||||
channel.next_layer().reset();
|
||||
|
||||
// Set up processor
|
||||
handshake_processor processor (params);
|
||||
handshake_processor processor(params);
|
||||
|
||||
// Read server greeting
|
||||
auto b = channel.read_one(channel.shared_sequence_number(), err);
|
||||
@@ -391,7 +405,8 @@ void boost::mysql::detail::handshake(
|
||||
|
||||
// Handshake response
|
||||
processor.compose_handshake_response(channel.shared_buffer());
|
||||
channel.write(boost::asio::buffer(channel.shared_buffer()), channel.shared_sequence_number(), err);
|
||||
channel
|
||||
.write(boost::asio::buffer(channel.shared_buffer()), channel.shared_sequence_number(), err);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
@@ -404,14 +419,23 @@ void boost::mysql::detail::handshake(
|
||||
return;
|
||||
|
||||
// Process it
|
||||
err = processor.process_handshake_server_response(b, channel.shared_buffer(), auth_outcome, info);
|
||||
err = processor.process_handshake_server_response(
|
||||
b,
|
||||
channel.shared_buffer(),
|
||||
auth_outcome,
|
||||
info
|
||||
);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
if (auth_outcome == auth_result::send_more_data)
|
||||
{
|
||||
// We received an auth switch request and we have the response ready to be sent
|
||||
channel.write(boost::asio::buffer(channel.shared_buffer()), channel.shared_sequence_number(), err);
|
||||
channel.write(
|
||||
boost::asio::buffer(channel.shared_buffer()),
|
||||
channel.shared_sequence_number(),
|
||||
err
|
||||
);
|
||||
if (err)
|
||||
return;
|
||||
}
|
||||
@@ -421,10 +445,7 @@ void boost::mysql::detail::handshake(
|
||||
}
|
||||
|
||||
template <class Stream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::detail::async_handshake(
|
||||
channel<Stream>& chan,
|
||||
const handshake_params& params,
|
||||
@@ -433,15 +454,11 @@ boost::mysql::detail::async_handshake(
|
||||
)
|
||||
{
|
||||
chan.reset();
|
||||
return boost::asio::async_compose<
|
||||
CompletionToken,
|
||||
void(error_code)
|
||||
>(
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code)>(
|
||||
handshake_op<Stream>(chan, info, params),
|
||||
token,
|
||||
chan
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,15 +10,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/prepare_statement.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/prepare_statement.hpp>
|
||||
#include <boost/mysql/detail/protocol/capabilities.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/statement_base.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -30,30 +31,31 @@ class prepare_statement_processor
|
||||
bytestring& write_buffer_;
|
||||
statement_base& output_;
|
||||
error_info& output_info_;
|
||||
unsigned remaining_meta_ {};
|
||||
unsigned remaining_meta_{};
|
||||
|
||||
public:
|
||||
template <class Stream>
|
||||
prepare_statement_processor(
|
||||
channel<Stream>& chan,
|
||||
statement_base& output,
|
||||
error_info& output_info
|
||||
) noexcept :
|
||||
caps_(chan.current_capabilities()),
|
||||
write_buffer_(chan.shared_buffer()),
|
||||
output_(output),
|
||||
output_info_(output_info)
|
||||
) noexcept
|
||||
: caps_(chan.current_capabilities()),
|
||||
write_buffer_(chan.shared_buffer()),
|
||||
output_(output),
|
||||
output_info_(output_info)
|
||||
{
|
||||
}
|
||||
|
||||
void process_request(boost::string_view statement)
|
||||
{
|
||||
com_stmt_prepare_packet packet { string_eof(statement) };
|
||||
com_stmt_prepare_packet packet{string_eof(statement)};
|
||||
serialize_message(packet, caps_, write_buffer_);
|
||||
}
|
||||
|
||||
void process_response(boost::asio::const_buffer message, void* channel, error_code& err)
|
||||
{
|
||||
deserialization_context ctx (message, caps_);
|
||||
deserialization_context ctx(message, caps_);
|
||||
std::uint8_t msg_type = 0;
|
||||
err = make_error_code(deserialize(ctx, msg_type));
|
||||
if (err)
|
||||
@@ -80,27 +82,19 @@ public:
|
||||
void on_meta_received() noexcept { --remaining_meta_; }
|
||||
};
|
||||
|
||||
template<class Stream>
|
||||
template <class Stream>
|
||||
struct prepare_statement_op : boost::asio::coroutine
|
||||
{
|
||||
channel<Stream>& chan_;
|
||||
prepare_statement_processor processor_;
|
||||
|
||||
prepare_statement_op(
|
||||
channel<Stream>& chan,
|
||||
const prepare_statement_processor& processor
|
||||
) :
|
||||
chan_(chan),
|
||||
processor_(processor)
|
||||
prepare_statement_op(channel<Stream>& chan, const prepare_statement_processor& processor)
|
||||
: chan_(chan), processor_(processor)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code err = {},
|
||||
boost::asio::const_buffer read_message = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code err = {}, boost::asio::const_buffer read_message = {})
|
||||
{
|
||||
// Error checking
|
||||
if (err)
|
||||
@@ -113,10 +107,17 @@ struct prepare_statement_op : boost::asio::coroutine
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
// Write message (already serialized at this point)
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_write(chan_.shared_buffer(), chan_.shared_sequence_number(), std::move(self));
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_write(
|
||||
chan_.shared_buffer(),
|
||||
chan_.shared_sequence_number(),
|
||||
std::move(self)
|
||||
);
|
||||
|
||||
// Read response
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_read_one(chan_.shared_sequence_number(), std::move(self));
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_read_one(
|
||||
chan_.shared_sequence_number(),
|
||||
std::move(self)
|
||||
);
|
||||
|
||||
// Process response
|
||||
processor_.process_response(read_message, &chan_, err);
|
||||
@@ -154,9 +155,9 @@ struct prepare_statement_op : boost::asio::coroutine
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::detail::prepare_statement(
|
||||
@@ -168,7 +169,7 @@ void boost::mysql::detail::prepare_statement(
|
||||
)
|
||||
{
|
||||
// Prepare message
|
||||
prepare_statement_processor processor (channel, output, info);
|
||||
prepare_statement_processor processor(channel, output, info);
|
||||
processor.process_request(statement);
|
||||
|
||||
// Write message
|
||||
@@ -203,10 +204,7 @@ void boost::mysql::detail::prepare_statement(
|
||||
}
|
||||
|
||||
template <class Stream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::detail::async_prepare_statement(
|
||||
channel<Stream>& chan,
|
||||
boost::string_view statement,
|
||||
@@ -215,7 +213,7 @@ boost::mysql::detail::async_prepare_statement(
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
prepare_statement_processor processor (chan, output, info);
|
||||
prepare_statement_processor processor(chan, output, info);
|
||||
processor.process_request(statement);
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code)>(
|
||||
prepare_statement_op(chan, processor),
|
||||
|
||||
@@ -10,40 +10,31 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/quit_connection.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/quit_connection.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <class Stream>
|
||||
void compose_quit(
|
||||
channel<Stream>& chan
|
||||
)
|
||||
void compose_quit(channel<Stream>& chan)
|
||||
{
|
||||
serialize_message(
|
||||
quit_packet(),
|
||||
chan.current_capabilities(),
|
||||
chan.shared_buffer()
|
||||
);
|
||||
serialize_message(quit_packet(), chan.current_capabilities(), chan.shared_buffer());
|
||||
}
|
||||
|
||||
template<class Stream>
|
||||
template <class Stream>
|
||||
struct quit_connection_op : boost::asio::coroutine
|
||||
{
|
||||
channel<Stream>& chan_;
|
||||
|
||||
quit_connection_op(channel<Stream>& chan) noexcept :
|
||||
chan_(chan) {}
|
||||
quit_connection_op(channel<Stream>& chan) noexcept : chan_(chan) {}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code err = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code err = {})
|
||||
{
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
@@ -66,16 +57,12 @@ struct quit_connection_op : boost::asio::coroutine
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::detail::quit_connection(
|
||||
channel<Stream>& chan,
|
||||
error_code& err,
|
||||
error_info&
|
||||
)
|
||||
void boost::mysql::detail::quit_connection(channel<Stream>& chan, error_code& err, error_info&)
|
||||
{
|
||||
compose_quit(chan);
|
||||
chan.write(chan.shared_buffer(), chan.shared_sequence_number(), err);
|
||||
@@ -91,15 +78,9 @@ void boost::mysql::detail::quit_connection(
|
||||
}
|
||||
|
||||
template <class Stream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
boost::mysql::detail::async_quit_connection(
|
||||
channel<Stream>& chan,
|
||||
CompletionToken&& token,
|
||||
error_info&
|
||||
)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::detail::
|
||||
async_quit_connection(channel<Stream>& chan, CompletionToken&& token, error_info&)
|
||||
{
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code)>(
|
||||
quit_connection_op<Stream>(chan),
|
||||
|
||||
@@ -12,14 +12,15 @@
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/read_all_rows.hpp>
|
||||
#include <boost/mysql/detail/protocol/deserialize_row.hpp>
|
||||
#include <boost/mysql/rows_view.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/mysql/rows_view.hpp>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -55,7 +56,7 @@ inline void process_all_rows(
|
||||
);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
|
||||
// If we received an EOF, we're done
|
||||
if (result.complete())
|
||||
{
|
||||
@@ -70,8 +71,7 @@ inline void process_all_rows(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Stream>
|
||||
template <class Stream>
|
||||
struct read_all_rows_op : boost::asio::coroutine
|
||||
{
|
||||
channel<Stream>& chan_;
|
||||
@@ -82,18 +82,13 @@ struct read_all_rows_op : boost::asio::coroutine
|
||||
channel<Stream>& chan,
|
||||
error_info& output_info,
|
||||
resultset_base& result
|
||||
) noexcept :
|
||||
chan_(chan),
|
||||
output_info_(output_info),
|
||||
resultset_(result)
|
||||
) noexcept
|
||||
: chan_(chan), output_info_(output_info), resultset_(result)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code err = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code err = {})
|
||||
{
|
||||
// Error checking
|
||||
if (err)
|
||||
@@ -138,10 +133,9 @@ struct read_all_rows_op : boost::asio::coroutine
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class Stream>
|
||||
boost::mysql::rows_view boost::mysql::detail::read_all_rows(
|
||||
@@ -167,7 +161,7 @@ boost::mysql::rows_view boost::mysql::detail::read_all_rows(
|
||||
channel.read_some(err, true);
|
||||
if (err)
|
||||
return rows_view();
|
||||
|
||||
|
||||
// Process read messages
|
||||
process_all_rows(channel, result, output, err, info);
|
||||
if (err)
|
||||
@@ -188,12 +182,8 @@ boost::mysql::detail::async_read_all_rows(
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code, rows_view)> (
|
||||
read_all_rows_op<Stream>(
|
||||
channel,
|
||||
output_info,
|
||||
result
|
||||
),
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code, rows_view)>(
|
||||
read_all_rows_op<Stream>(channel, output_info, result),
|
||||
token,
|
||||
channel
|
||||
);
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
#include <boost/mysql/detail/protocol/deserialize_row.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/row_view.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
@@ -56,30 +58,20 @@ inline row_view process_one_row(
|
||||
}
|
||||
}
|
||||
|
||||
template<class Stream>
|
||||
template <class Stream>
|
||||
struct read_one_row_op : boost::asio::coroutine
|
||||
{
|
||||
channel<Stream>& chan_;
|
||||
error_info& output_info_;
|
||||
resultset_base& resultset_;
|
||||
|
||||
read_one_row_op(
|
||||
channel<Stream>& chan,
|
||||
error_info& output_info,
|
||||
resultset_base& result
|
||||
) noexcept :
|
||||
chan_(chan),
|
||||
output_info_(output_info),
|
||||
resultset_(result)
|
||||
read_one_row_op(channel<Stream>& chan, error_info& output_info, resultset_base& result) noexcept
|
||||
: chan_(chan), output_info_(output_info), resultset_(result)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code err = {},
|
||||
boost::asio::const_buffer read_message = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code err = {}, boost::asio::const_buffer read_message = {})
|
||||
{
|
||||
// Error checking
|
||||
if (err)
|
||||
@@ -101,25 +93,21 @@ struct read_one_row_op : boost::asio::coroutine
|
||||
}
|
||||
|
||||
// Read the message
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_read_one(resultset_.sequence_number(), std::move(self));
|
||||
BOOST_ASIO_CORO_YIELD chan_.async_read_one(
|
||||
resultset_.sequence_number(),
|
||||
std::move(self)
|
||||
);
|
||||
|
||||
// Process it
|
||||
result = process_one_row(
|
||||
chan_,
|
||||
read_message,
|
||||
resultset_,
|
||||
err,
|
||||
output_info_
|
||||
);
|
||||
result = process_one_row(chan_, read_message, resultset_, err, output_info_);
|
||||
self.complete(err, result);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class Stream>
|
||||
boost::mysql::row_view boost::mysql::detail::read_one_row(
|
||||
@@ -140,13 +128,7 @@ boost::mysql::row_view boost::mysql::detail::read_one_row(
|
||||
if (err)
|
||||
return row_view();
|
||||
|
||||
return process_one_row(
|
||||
channel,
|
||||
read_message,
|
||||
result,
|
||||
err,
|
||||
info
|
||||
);
|
||||
return process_one_row(channel, read_message, result, err, info);
|
||||
}
|
||||
|
||||
template <class Stream, class CompletionToken>
|
||||
@@ -161,12 +143,8 @@ boost::mysql::detail::async_read_one_row(
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code, row_view)> (
|
||||
read_one_row_op<Stream>(
|
||||
channel,
|
||||
output_info,
|
||||
result
|
||||
),
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code, row_view)>(
|
||||
read_one_row_op<Stream>(channel, output_info, result),
|
||||
token,
|
||||
channel
|
||||
);
|
||||
|
||||
@@ -13,12 +13,13 @@
|
||||
#include <boost/mysql/detail/network_algorithms/read_some_rows.hpp>
|
||||
#include <boost/mysql/detail/protocol/deserialize_row.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/row.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/mysql/row.hpp>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -55,7 +56,7 @@ inline rows_view process_some_rows(
|
||||
);
|
||||
if (err)
|
||||
return rows_view();
|
||||
|
||||
|
||||
// There is no need to copy strings values anywhere; the returned values
|
||||
// will point into the channel's internal buffer
|
||||
|
||||
@@ -73,8 +74,7 @@ inline rows_view process_some_rows(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Stream>
|
||||
template <class Stream>
|
||||
struct read_some_rows_op : boost::asio::coroutine
|
||||
{
|
||||
channel<Stream>& chan_;
|
||||
@@ -85,18 +85,13 @@ struct read_some_rows_op : boost::asio::coroutine
|
||||
channel<Stream>& chan,
|
||||
error_info& output_info,
|
||||
resultset_base& result
|
||||
) noexcept :
|
||||
chan_(chan),
|
||||
output_info_(output_info),
|
||||
resultset_(result)
|
||||
) noexcept
|
||||
: chan_(chan), output_info_(output_info), resultset_(result)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Self>
|
||||
void operator()(
|
||||
Self& self,
|
||||
error_code err = {}
|
||||
)
|
||||
template <class Self>
|
||||
void operator()(Self& self, error_code err = {})
|
||||
{
|
||||
// Error checking
|
||||
if (err)
|
||||
@@ -122,16 +117,15 @@ struct read_some_rows_op : boost::asio::coroutine
|
||||
|
||||
// Process messages
|
||||
output = process_some_rows(chan_, resultset_, err, output_info_);
|
||||
|
||||
|
||||
self.complete(err, output);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
template <class Stream>
|
||||
boost::mysql::rows_view boost::mysql::detail::read_some_rows(
|
||||
@@ -168,12 +162,8 @@ boost::mysql::detail::async_read_some_rows(
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code, rows_view)> (
|
||||
read_some_rows_op<Stream>(
|
||||
channel,
|
||||
output_info,
|
||||
result
|
||||
),
|
||||
return boost::asio::async_compose<CompletionToken, void(error_code, rows_view)>(
|
||||
read_some_rows_op<Stream>(channel, output_info, result),
|
||||
token,
|
||||
channel
|
||||
);
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_PREPARE_STATEMENT_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_PREPARE_STATEMENT_HPP
|
||||
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/statement_base.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -37,9 +37,9 @@ async_prepare_statement(
|
||||
CompletionToken&& token
|
||||
);
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/prepare_statement.hpp>
|
||||
|
||||
|
||||
@@ -8,32 +8,23 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_QUIT_CONNECTION_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_QUIT_CONNECTION_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <class Stream>
|
||||
void quit_connection(
|
||||
channel<Stream>& chan,
|
||||
error_code& code,
|
||||
error_info& info
|
||||
);
|
||||
void quit_connection(channel<Stream>& chan, error_code& code, error_info& info);
|
||||
|
||||
template <class Stream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_quit_connection(
|
||||
channel<Stream>& chan,
|
||||
CompletionToken&& token,
|
||||
error_info& info
|
||||
);
|
||||
async_quit_connection(channel<Stream>& chan, CompletionToken&& token, error_info& info);
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/quit_connection.hpp>
|
||||
|
||||
|
||||
@@ -8,23 +8,18 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_READ_ALL_ROWS_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_READ_ALL_ROWS_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/rows_view.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <class Stream>
|
||||
rows_view read_all_rows(
|
||||
channel<Stream>& channel,
|
||||
resultset_base& result,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
);
|
||||
rows_view
|
||||
read_all_rows(channel<Stream>& channel, resultset_base& result, error_code& err, error_info& info);
|
||||
|
||||
template <class Stream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, rows_view))
|
||||
@@ -35,13 +30,10 @@ async_read_all_rows(
|
||||
CompletionToken&& token
|
||||
);
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/read_all_rows.hpp>
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_MYSQL_IMPL_NETWORK_ALGORITHMS_READ_TEXT_ROW_HPP_ */
|
||||
|
||||
@@ -8,23 +8,18 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_READ_ONE_ROW_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_READ_ONE_ROW_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/row.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <class Stream>
|
||||
row_view read_one_row(
|
||||
channel<Stream>& channel,
|
||||
resultset_base& result,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
);
|
||||
row_view
|
||||
read_one_row(channel<Stream>& channel, resultset_base& result, error_code& err, error_info& info);
|
||||
|
||||
template <class Stream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, row_view))
|
||||
@@ -35,13 +30,10 @@ async_read_one_row(
|
||||
CompletionToken&& token
|
||||
);
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/read_one_row.hpp>
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_MYSQL_IMPL_NETWORK_ALGORITHMS_READ_TEXT_ROW_HPP_ */
|
||||
|
||||
@@ -8,23 +8,18 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_READ_SOME_ROWS_HPP
|
||||
#define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_READ_SOME_ROWS_HPP
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/rows_view.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <class Stream>
|
||||
rows_view read_some_rows(
|
||||
channel<Stream>& channel,
|
||||
resultset_base& result,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
);
|
||||
rows_view
|
||||
read_some_rows(channel<Stream>& channel, resultset_base& result, error_code& err, error_info& info);
|
||||
|
||||
template <class Stream, class CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, rows_view))
|
||||
@@ -35,13 +30,10 @@ async_read_some_rows(
|
||||
CompletionToken&& token
|
||||
);
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/impl/read_some_rows.hpp>
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_MYSQL_IMPL_NETWORK_ALGORITHMS_READ_TEXT_ROW_HPP_ */
|
||||
|
||||
@@ -8,27 +8,27 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_PROTOCOL_BINARY_SERIALIZATION_HPP
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_BINARY_SERIALIZATION_HPP
|
||||
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/detail/protocol/serialization.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
template <>
|
||||
struct serialization_traits<field_view, serialization_tag::none> :
|
||||
noop_deserialize<field_view>
|
||||
struct serialization_traits<field_view, serialization_tag::none> : noop_deserialize<field_view>
|
||||
{
|
||||
static inline std::size_t get_size_(const serialization_context& ctx,
|
||||
const field_view& input) noexcept;
|
||||
static inline void serialize_(serialization_context& ctx,
|
||||
const field_view& input) noexcept;
|
||||
static inline std::size_t get_size_(
|
||||
const serialization_context& ctx,
|
||||
const field_view& input
|
||||
) noexcept;
|
||||
|
||||
static inline void serialize_(serialization_context& ctx, const field_view& input) noexcept;
|
||||
};
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/protocol/impl/binary_serialization.ipp>
|
||||
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace boost {
|
||||
@@ -19,29 +21,26 @@ namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
// All BIT values come as binary values between 1 and 8 bytes length packed in string_lenenc's,
|
||||
// for both the text and the binary protocols. As the text protocol already unpacks the string_lenenc layer,
|
||||
// this function is in charge of just parsing the binary payload.
|
||||
// The length of the BIT value depends on how the type was defined in the table (e.g. BIT(14) will send
|
||||
// a 2 byte value; BIT(54) will send a 7 byte one). Values are sent as big-endian.
|
||||
inline errc deserialize_bit(
|
||||
boost::string_view from,
|
||||
field_view& to
|
||||
) noexcept
|
||||
// for both the text and the binary protocols. As the text protocol already unpacks the
|
||||
// string_lenenc layer, this function is in charge of just parsing the binary payload. The length of
|
||||
// the BIT value depends on how the type was defined in the table (e.g. BIT(14) will send a 2 byte
|
||||
// value; BIT(54) will send a 7 byte one). Values are sent as big-endian.
|
||||
inline errc deserialize_bit(boost::string_view from, field_view& to) noexcept
|
||||
{
|
||||
std::size_t num_bytes = from.size();
|
||||
if (num_bytes < 1 || num_bytes > 8)
|
||||
{
|
||||
return errc::protocol_value_error;
|
||||
}
|
||||
unsigned char temp [8] {};
|
||||
unsigned char temp[8]{};
|
||||
unsigned char* dest = temp + sizeof(temp) - num_bytes;
|
||||
std::memcpy(dest, from.data(), num_bytes);
|
||||
to = field_view(boost::endian::load_big_u64(temp));
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -15,6 +15,7 @@ namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
// Server/client capabilities
|
||||
// clang-format off
|
||||
constexpr std::uint32_t CLIENT_LONG_PASSWORD = 1; // Use the improved version of Old Password Authentication
|
||||
constexpr std::uint32_t CLIENT_FOUND_ROWS = 2; // Send found rows instead of affected rows in EOF_Packet
|
||||
constexpr std::uint32_t CLIENT_LONG_FLAG = 4; // Get all column flags
|
||||
@@ -43,73 +44,93 @@ constexpr std::uint32_t CLIENT_DEPRECATE_EOF = (1UL << 24); // Client no longer
|
||||
constexpr std::uint32_t CLIENT_SSL_VERIFY_SERVER_CERT = (1UL << 30); // Verify server certificate
|
||||
constexpr std::uint32_t CLIENT_OPTIONAL_RESULTSET_METADATA = (1UL << 25); // The client can handle optional metadata information in the resultset
|
||||
constexpr std::uint32_t CLIENT_REMEMBER_OPTIONS = (1UL << 31); // Don't reset the options after an unsuccessful connect
|
||||
// clang-format on
|
||||
|
||||
class capabilities
|
||||
{
|
||||
std::uint32_t value_;
|
||||
|
||||
public:
|
||||
constexpr explicit capabilities(std::uint32_t value=0) noexcept : value_(value) {};
|
||||
constexpr explicit capabilities(std::uint32_t value = 0) noexcept : value_(value){};
|
||||
constexpr std::uint32_t get() const noexcept { return value_; }
|
||||
void set(std::uint32_t value) noexcept { value_ = value; }
|
||||
constexpr bool has(std::uint32_t cap) const noexcept { return value_ & cap; }
|
||||
constexpr bool has_all(capabilities other) const noexcept { return (value_ & other.get()) == other.get(); }
|
||||
constexpr capabilities operator|(capabilities rhs) const noexcept { return capabilities(value_ | rhs.value_); }
|
||||
constexpr capabilities operator&(capabilities rhs) const noexcept { return capabilities(value_ & rhs.value_); }
|
||||
constexpr bool operator==(const capabilities& rhs) const noexcept { return value_ == rhs.value_; }
|
||||
constexpr bool operator!=(const capabilities& rhs) const noexcept { return value_ != rhs.value_; }
|
||||
constexpr bool has_all(capabilities other) const noexcept
|
||||
{
|
||||
return (value_ & other.get()) == other.get();
|
||||
}
|
||||
constexpr capabilities operator|(capabilities rhs) const noexcept
|
||||
{
|
||||
return capabilities(value_ | rhs.value_);
|
||||
}
|
||||
constexpr capabilities operator&(capabilities rhs) const noexcept
|
||||
{
|
||||
return capabilities(value_ & rhs.value_);
|
||||
}
|
||||
constexpr bool operator==(const capabilities& rhs) const noexcept
|
||||
{
|
||||
return value_ == rhs.value_;
|
||||
}
|
||||
constexpr bool operator!=(const capabilities& rhs) const noexcept
|
||||
{
|
||||
return value_ != rhs.value_;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* CLIENT_LONG_PASSWORD: unset // Use the improved version of Old Password Authentication
|
||||
* CLIENT_FOUND_ROWS: unset // Send found rows instead of affected rows in EOF_Packet
|
||||
* CLIENT_LONG_FLAG: unset // Get all column flags
|
||||
* CLIENT_CONNECT_WITH_DB: optional // Database (schema) name can be specified on connect in Handshake Response Packet
|
||||
* CLIENT_NO_SCHEMA: unset // Don't allow database.table.column
|
||||
* CLIENT_COMPRESS: unset // Compression protocol supported
|
||||
* CLIENT_ODBC: unset // Special handling of ODBC behavior
|
||||
* CLIENT_LOCAL_FILES: unset // Can use LOAD DATA LOCAL
|
||||
* CLIENT_IGNORE_SPACE: unset // Ignore spaces before '('
|
||||
* CLIENT_PROTOCOL_41: mandatory // New 4.1 protocol
|
||||
* CLIENT_INTERACTIVE: unset // This is an interactive client
|
||||
* CLIENT_SSL: unset // Use SSL encryption for the session
|
||||
* CLIENT_IGNORE_SIGPIPE: unset // Client only flag
|
||||
* CLIENT_TRANSACTIONS: unset // Client knows about transactions
|
||||
* CLIENT_RESERVED: unset // DEPRECATED: Old flag for 4.1 protocol
|
||||
* CLIENT_RESERVED2: unset // DEPRECATED: Old flag for 4.1 authentication \ CLIENT_SECURE_CONNECTION
|
||||
* CLIENT_MULTI_STATEMENTS: unset // Enable/disable multi-stmt support
|
||||
* CLIENT_MULTI_RESULTS: unset // Enable/disable multi-results
|
||||
* CLIENT_PS_MULTI_RESULTS: unset // Multi-results and OUT parameters in PS-protocol
|
||||
* CLIENT_PLUGIN_AUTH: mandatory // Client supports plugin authentication
|
||||
* CLIENT_CONNECT_ATTRS: unset // Client supports connection attributes
|
||||
* CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA: mandatory // Enable authentication response packet to be larger than 255 bytes
|
||||
* CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS: unset // Don't close the connection for a user account with expired password
|
||||
* CLIENT_SESSION_TRACK: unset // Capable of handling server state change information
|
||||
* CLIENT_DEPRECATE_EOF: mandatory // Client no longer needs EOF_Packet and will use OK_Packet instead
|
||||
* CLIENT_SSL_VERIFY_SERVER_CERT: unset // Verify server certificate
|
||||
* CLIENT_OPTIONAL_RESULTSET_METADATA: unset // The client can handle optional metadata information in the resultset
|
||||
* CLIENT_REMEMBER_OPTIONS: unset // Don't reset the options after an unsuccessful connect
|
||||
*
|
||||
* We pay attention to:
|
||||
* CLIENT_CONNECT_WITH_DB: optional // Database (schema) name can be specified on connect in Handshake Response Packet
|
||||
* CLIENT_PROTOCOL_41: mandatory // New 4.1 protocol
|
||||
* CLIENT_PLUGIN_AUTH: mandatory // Client supports plugin authentication
|
||||
* CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA: mandatory // Enable authentication response packet to be larger than 255 bytes
|
||||
* CLIENT_DEPRECATE_EOF: mandatory // Client no longer needs EOF_Packet and will use OK_Packet instead
|
||||
* CLIENT_LONG_PASSWORD: unset // Use the improved version of Old Password Authentication
|
||||
* CLIENT_FOUND_ROWS: unset // Send found rows instead of affected rows in EOF_Packet
|
||||
* CLIENT_LONG_FLAG: unset // Get all column flags
|
||||
* CLIENT_CONNECT_WITH_DB: optional // Database (schema) name can be specified on connect in
|
||||
* Handshake Response Packet CLIENT_NO_SCHEMA: unset // Don't allow database.table.column
|
||||
* CLIENT_COMPRESS: unset // Compression protocol supported
|
||||
* CLIENT_ODBC: unset // Special handling of ODBC behavior
|
||||
* CLIENT_LOCAL_FILES: unset // Can use LOAD DATA LOCAL
|
||||
* CLIENT_IGNORE_SPACE: unset // Ignore spaces before '('
|
||||
* CLIENT_PROTOCOL_41: mandatory // New 4.1 protocol
|
||||
* CLIENT_INTERACTIVE: unset // This is an interactive client
|
||||
* CLIENT_SSL: unset // Use SSL encryption for the session
|
||||
* CLIENT_IGNORE_SIGPIPE: unset // Client only flag
|
||||
* CLIENT_TRANSACTIONS: unset // Client knows about transactions
|
||||
* CLIENT_RESERVED: unset // DEPRECATED: Old flag for 4.1 protocol
|
||||
* CLIENT_RESERVED2: unset // DEPRECATED: Old flag for 4.1 authentication
|
||||
* \ CLIENT_SECURE_CONNECTION CLIENT_MULTI_STATEMENTS: unset // Enable/disable multi-stmt support
|
||||
* CLIENT_MULTI_RESULTS: unset // Enable/disable multi-results
|
||||
* CLIENT_PS_MULTI_RESULTS: unset // Multi-results and OUT parameters in PS-protocol
|
||||
* CLIENT_PLUGIN_AUTH: mandatory // Client supports plugin authentication
|
||||
* CLIENT_CONNECT_ATTRS: unset // Client supports connection attributes
|
||||
* CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA: mandatory // Enable authentication response packet to be
|
||||
* larger than 255 bytes CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS: unset // Don't close the connection
|
||||
* for a user account with expired password CLIENT_SESSION_TRACK: unset // Capable of handling
|
||||
* server state change information CLIENT_DEPRECATE_EOF: mandatory // Client no longer needs
|
||||
* EOF_Packet and will use OK_Packet instead CLIENT_SSL_VERIFY_SERVER_CERT: unset // Verify server
|
||||
* certificate CLIENT_OPTIONAL_RESULTSET_METADATA: unset // The client can handle optional metadata
|
||||
* information in the resultset CLIENT_REMEMBER_OPTIONS: unset // Don't reset the options after an
|
||||
* unsuccessful connect
|
||||
*
|
||||
* We pay attention to:
|
||||
* CLIENT_CONNECT_WITH_DB: optional // Database (schema) name can be specified on connect in
|
||||
* Handshake Response Packet CLIENT_PROTOCOL_41: mandatory // New 4.1 protocol CLIENT_PLUGIN_AUTH:
|
||||
* mandatory // Client supports plugin authentication CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA:
|
||||
* mandatory // Enable authentication response packet to be larger than 255 bytes
|
||||
* CLIENT_DEPRECATE_EOF: mandatory // Client no longer needs EOF_Packet and will use OK_Packet
|
||||
* instead
|
||||
*/
|
||||
|
||||
constexpr capabilities mandatory_capabilities {
|
||||
// clang-format off
|
||||
constexpr capabilities mandatory_capabilities{
|
||||
CLIENT_PROTOCOL_41 |
|
||||
CLIENT_PLUGIN_AUTH |
|
||||
CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA |
|
||||
CLIENT_DEPRECATE_EOF |
|
||||
CLIENT_SECURE_CONNECTION
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
constexpr capabilities optional_capabilities {0};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
constexpr capabilities optional_capabilities{0};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_PROTOCOL_COMMON_MESSAGES_HPP
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_COMMON_MESSAGES_HPP
|
||||
|
||||
#include <boost/mysql/detail/protocol/serialization.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
#include <boost/mysql/collation.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
#include <boost/mysql/detail/protocol/serialization.hpp>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace boost {
|
||||
@@ -26,10 +27,7 @@ struct packet_header
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
std::forward<Callable>(cb)(
|
||||
self.packet_size,
|
||||
self.sequence_number
|
||||
);
|
||||
std::forward<Callable>(cb)(self.packet_size, self.sequence_number);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -39,7 +37,7 @@ struct ok_packet
|
||||
// header: int<1> header 0x00 or 0xFE the OK packet header
|
||||
int_lenenc affected_rows;
|
||||
int_lenenc last_insert_id;
|
||||
std::uint16_t status_flags; // server_status_flags
|
||||
std::uint16_t status_flags; // server_status_flags
|
||||
std::uint16_t warnings;
|
||||
// CLIENT_SESSION_TRACK: not implemented
|
||||
string_lenenc info;
|
||||
@@ -47,6 +45,7 @@ struct ok_packet
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
// clang-format off
|
||||
std::forward<Callable>(cb)(
|
||||
self.affected_rows,
|
||||
self.last_insert_id,
|
||||
@@ -54,12 +53,13 @@ struct ok_packet
|
||||
self.warnings,
|
||||
self.info
|
||||
);
|
||||
// clang-format on
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct serialization_traits<ok_packet, serialization_tag::struct_with_fields> :
|
||||
noop_serialize<ok_packet>
|
||||
struct serialization_traits<ok_packet, serialization_tag::struct_with_fields>
|
||||
: noop_serialize<ok_packet>
|
||||
{
|
||||
static inline errc deserialize_(deserialization_context& ctx, ok_packet& output) noexcept;
|
||||
};
|
||||
@@ -76,12 +76,14 @@ struct err_packet
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
// clang-format off
|
||||
std::forward<Callable>(cb)(
|
||||
self.error_code,
|
||||
self.sql_state_marker,
|
||||
self.sql_state,
|
||||
self.error_message
|
||||
);
|
||||
// clang-format on
|
||||
}
|
||||
};
|
||||
|
||||
@@ -90,21 +92,23 @@ static_assert(is_struct_with_fields<err_packet>(), "Bad!");
|
||||
// col def
|
||||
struct column_definition_packet
|
||||
{
|
||||
string_lenenc catalog; // always "def"
|
||||
string_lenenc catalog; // always "def"
|
||||
string_lenenc schema;
|
||||
string_lenenc table; // virtual table
|
||||
string_lenenc org_table; // physical table
|
||||
string_lenenc name; // virtual column name
|
||||
string_lenenc org_name; // physical column name
|
||||
string_lenenc table; // virtual table
|
||||
string_lenenc org_table; // physical table
|
||||
string_lenenc name; // virtual column name
|
||||
string_lenenc org_name; // physical column name
|
||||
collation character_set;
|
||||
std::uint32_t column_length; // maximum length of the field
|
||||
protocol_field_type type; // type of the column as defined in enum_field_types
|
||||
std::uint16_t flags; // Flags as defined in Column Definition Flags
|
||||
std::uint8_t decimals; // max shown decimal digits. 0x00 for int/static strings; 0x1f for dynamic strings, double, float
|
||||
std::uint32_t column_length; // maximum length of the field
|
||||
protocol_field_type type; // type of the column as defined in enum_field_types
|
||||
std::uint16_t flags; // Flags as defined in Column Definition Flags
|
||||
std::uint8_t decimals; // max shown decimal digits. 0x00 for int/static strings; 0x1f for
|
||||
// dynamic strings, double, float
|
||||
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
// clang-format off
|
||||
std::forward<Callable>(cb)(
|
||||
self.catalog,
|
||||
self.schema,
|
||||
@@ -118,14 +122,18 @@ struct column_definition_packet
|
||||
self.flags,
|
||||
self.decimals
|
||||
);
|
||||
// clang-format on
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct serialization_traits<column_definition_packet, serialization_tag::struct_with_fields> :
|
||||
noop_serialize<column_definition_packet>
|
||||
struct serialization_traits<column_definition_packet, serialization_tag::struct_with_fields>
|
||||
: noop_serialize<column_definition_packet>
|
||||
{
|
||||
static inline errc deserialize_(deserialization_context& ctx, column_definition_packet& output) noexcept;
|
||||
static inline errc deserialize_(
|
||||
deserialization_context& ctx,
|
||||
column_definition_packet& output
|
||||
) noexcept;
|
||||
};
|
||||
|
||||
// connection quit
|
||||
@@ -134,16 +142,17 @@ struct quit_packet
|
||||
static constexpr std::uint8_t command_id = 0x01;
|
||||
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self&, Callable&&) noexcept {}
|
||||
static void apply(Self&, Callable&&) noexcept
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// aux
|
||||
inline error_code process_error_packet(deserialization_context& ctx, error_info& info);
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/protocol/impl/common_messages.ipp>
|
||||
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_PROTOCOL_CONSTANTS_HPP
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_CONSTANTS_HPP
|
||||
|
||||
#include <boost/mysql/detail/protocol/protocol_types.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/make_string_view.hpp>
|
||||
#include <boost/mysql/detail/protocol/protocol_types.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
@@ -18,35 +19,34 @@ namespace detail {
|
||||
|
||||
enum class protocol_field_type : std::uint8_t
|
||||
{
|
||||
decimal = 0x00, // Apparently not sent
|
||||
tiny = 0x01, // TINYINT
|
||||
short_ = 0x02, // SMALLINT
|
||||
long_ = 0x03, // INT
|
||||
float_ = 0x04, // FLOAT
|
||||
double_ = 0x05, // DOUBLE
|
||||
null = 0x06, // Apparently not sent
|
||||
timestamp = 0x07, // TIMESTAMP
|
||||
longlong = 0x08, // BIGINT
|
||||
int24 = 0x09, // MEDIUMINT
|
||||
date = 0x0a, // DATE
|
||||
time = 0x0b, // TIME
|
||||
datetime = 0x0c, // DATETIME
|
||||
year = 0x0d, // YEAR
|
||||
varchar = 0x0f, // Apparently not sent
|
||||
bit = 0x10, // BIT
|
||||
newdecimal = 0xf6, // DECIMAL
|
||||
enum_ = 0xf7, // Apparently not sent
|
||||
set = 0xf8, // Apperently not sent
|
||||
tiny_blob = 0xf9, // Apparently not sent
|
||||
medium_blob = 0xfa,// Apparently not sent
|
||||
long_blob = 0xfb, // Apparently not sent
|
||||
blob = 0xfc, // Used for all TEXT and BLOB types
|
||||
var_string = 0xfd, // Used for VARCHAR and VARBINARY
|
||||
string = 0xfe, // Used for CHAR and BINARY, ENUM (enum flag set), SET (set flag set)
|
||||
geometry = 0xff // GEOMETRY
|
||||
decimal = 0x00, // Apparently not sent
|
||||
tiny = 0x01, // TINYINT
|
||||
short_ = 0x02, // SMALLINT
|
||||
long_ = 0x03, // INT
|
||||
float_ = 0x04, // FLOAT
|
||||
double_ = 0x05, // DOUBLE
|
||||
null = 0x06, // Apparently not sent
|
||||
timestamp = 0x07, // TIMESTAMP
|
||||
longlong = 0x08, // BIGINT
|
||||
int24 = 0x09, // MEDIUMINT
|
||||
date = 0x0a, // DATE
|
||||
time = 0x0b, // TIME
|
||||
datetime = 0x0c, // DATETIME
|
||||
year = 0x0d, // YEAR
|
||||
varchar = 0x0f, // Apparently not sent
|
||||
bit = 0x10, // BIT
|
||||
newdecimal = 0xf6, // DECIMAL
|
||||
enum_ = 0xf7, // Apparently not sent
|
||||
set = 0xf8, // Apperently not sent
|
||||
tiny_blob = 0xf9, // Apparently not sent
|
||||
medium_blob = 0xfa, // Apparently not sent
|
||||
long_blob = 0xfb, // Apparently not sent
|
||||
blob = 0xfc, // Used for all TEXT and BLOB types
|
||||
var_string = 0xfd, // Used for VARCHAR and VARBINARY
|
||||
string = 0xfe, // Used for CHAR and BINARY, ENUM (enum flag set), SET (set flag set)
|
||||
geometry = 0xff // GEOMETRY
|
||||
};
|
||||
|
||||
|
||||
constexpr std::size_t MAX_PACKET_SIZE = 0xffffff;
|
||||
constexpr std::size_t HEADER_SIZE = 4;
|
||||
|
||||
@@ -64,7 +64,7 @@ constexpr std::uint32_t SERVER_STATUS_METADATA_CHANGED = 1024;
|
||||
constexpr std::uint32_t SERVER_QUERY_WAS_SLOW = 2048;
|
||||
constexpr std::uint32_t SERVER_PS_OUT_PARAMS = 4096;
|
||||
constexpr std::uint32_t SERVER_STATUS_IN_TRANS_READONLY = 8192;
|
||||
constexpr std::uint32_t SERVER_SESSION_STATE_CHANGED = (1UL << 14) ;
|
||||
constexpr std::uint32_t SERVER_SESSION_STATE_CHANGED = (1UL << 14);
|
||||
|
||||
// Packet type constants
|
||||
constexpr std::uint8_t handshake_protocol_version_9 = 9;
|
||||
@@ -79,24 +79,24 @@ constexpr boost::string_view fast_auth_complete_challenge = make_string_view("\3
|
||||
// Column flags
|
||||
namespace column_flags {
|
||||
|
||||
constexpr std::uint16_t not_null = 1; // Field can't be NULL.
|
||||
constexpr std::uint16_t pri_key = 2; // Field is part of a primary key.
|
||||
constexpr std::uint16_t unique_key = 4; // Field is part of a unique key.
|
||||
constexpr std::uint16_t multiple_key = 8; // Field is part of a key.
|
||||
constexpr std::uint16_t blob = 16; // Field is a blob.
|
||||
constexpr std::uint16_t unsigned_ = 32; // Field is unsigned.
|
||||
constexpr std::uint16_t zerofill = 64; // Field is zerofill.
|
||||
constexpr std::uint16_t binary = 128; // Field is binary.
|
||||
constexpr std::uint16_t enum_ = 256; // field is an enum
|
||||
constexpr std::uint16_t not_null = 1; // Field can't be NULL.
|
||||
constexpr std::uint16_t pri_key = 2; // Field is part of a primary key.
|
||||
constexpr std::uint16_t unique_key = 4; // Field is part of a unique key.
|
||||
constexpr std::uint16_t multiple_key = 8; // Field is part of a key.
|
||||
constexpr std::uint16_t blob = 16; // Field is a blob.
|
||||
constexpr std::uint16_t unsigned_ = 32; // Field is unsigned.
|
||||
constexpr std::uint16_t zerofill = 64; // Field is zerofill.
|
||||
constexpr std::uint16_t binary = 128; // Field is binary.
|
||||
constexpr std::uint16_t enum_ = 256; // field is an enum
|
||||
constexpr std::uint16_t auto_increment = 512; // field is a autoincrement field
|
||||
constexpr std::uint16_t timestamp = 1024; // Field is a timestamp.
|
||||
constexpr std::uint16_t set = 2048; // field is a set
|
||||
constexpr std::uint16_t no_default_value = 4096; // Field doesn't have default value.
|
||||
constexpr std::uint16_t timestamp = 1024; // Field is a timestamp.
|
||||
constexpr std::uint16_t set = 2048; // field is a set
|
||||
constexpr std::uint16_t no_default_value = 4096; // Field doesn't have default value.
|
||||
constexpr std::uint16_t on_update_now = 8192; // Field is set to NOW on UPDATE.
|
||||
constexpr std::uint16_t part_key = 16384; // Intern; Part of some key.
|
||||
constexpr std::uint16_t num = 32768; // Field is num (for clients)
|
||||
constexpr std::uint16_t part_key = 16384; // Intern; Part of some key.
|
||||
constexpr std::uint16_t num = 32768; // Field is num (for clients)
|
||||
|
||||
} // column_flags
|
||||
} // namespace column_flags
|
||||
|
||||
// Prepared statements
|
||||
namespace cursor_types {
|
||||
@@ -106,7 +106,7 @@ constexpr std::uint8_t read_only = 1;
|
||||
constexpr std::uint8_t for_update = 2;
|
||||
constexpr std::uint8_t scrollable = 4;
|
||||
|
||||
} // cursor_types
|
||||
} // namespace cursor_types
|
||||
|
||||
// Text protocol deserialization constants
|
||||
namespace textc {
|
||||
@@ -116,24 +116,25 @@ constexpr unsigned max_decimals = 6u;
|
||||
constexpr std::size_t year_sz = 4;
|
||||
constexpr std::size_t month_sz = 2;
|
||||
constexpr std::size_t day_sz = 2;
|
||||
constexpr std::size_t hours_min_sz = 2; // in TIME, it may be longer
|
||||
constexpr std::size_t hours_min_sz = 2; // in TIME, it may be longer
|
||||
constexpr std::size_t mins_sz = 2;
|
||||
constexpr std::size_t secs_sz = 2;
|
||||
|
||||
constexpr std::size_t date_sz = year_sz + month_sz + day_sz + 2; // delimiters
|
||||
constexpr std::size_t time_min_sz = hours_min_sz + mins_sz + secs_sz + 2; // delimiters
|
||||
constexpr std::size_t time_max_sz = time_min_sz + max_decimals + 3; // sign, period, hour extra character
|
||||
constexpr std::size_t datetime_min_sz = date_sz + time_min_sz + 1; // delimiter
|
||||
constexpr std::size_t datetime_max_sz = datetime_min_sz + max_decimals + 1; // period
|
||||
constexpr std::size_t date_sz = year_sz + month_sz + day_sz + 2; // delimiters
|
||||
constexpr std::size_t time_min_sz = hours_min_sz + mins_sz + secs_sz + 2; // delimiters
|
||||
constexpr std::size_t time_max_sz =
|
||||
time_min_sz + max_decimals + 3; // sign, period, hour extra character
|
||||
constexpr std::size_t datetime_min_sz = date_sz + time_min_sz + 1; // delimiter
|
||||
constexpr std::size_t datetime_max_sz = datetime_min_sz + max_decimals + 1; // period
|
||||
|
||||
constexpr unsigned time_max_hour = 838;
|
||||
|
||||
} // textc
|
||||
} // namespace textc
|
||||
|
||||
// Binary protocol (de)serialization constants
|
||||
namespace binc {
|
||||
|
||||
constexpr std::size_t length_sz = 1; // length byte, for date, datetime and time
|
||||
constexpr std::size_t length_sz = 1; // length byte, for date, datetime and time
|
||||
constexpr std::size_t year_sz = 2;
|
||||
constexpr std::size_t month_sz = 1;
|
||||
constexpr std::size_t date_day_sz = 1;
|
||||
@@ -144,7 +145,7 @@ constexpr std::size_t secs_sz = 1;
|
||||
constexpr std::size_t micros_sz = 4;
|
||||
constexpr std::size_t time_sign_sz = 1;
|
||||
|
||||
constexpr std::size_t date_sz = year_sz + month_sz + date_day_sz; // does not include length
|
||||
constexpr std::size_t date_sz = year_sz + month_sz + date_day_sz; // does not include length
|
||||
|
||||
constexpr std::size_t datetime_d_sz = date_sz;
|
||||
constexpr std::size_t datetime_dhms_sz = datetime_d_sz + hours_sz + mins_sz + secs_sz;
|
||||
@@ -153,9 +154,9 @@ constexpr std::size_t datetime_dhmsu_sz = datetime_dhms_sz + micros_sz;
|
||||
constexpr std::size_t time_dhms_sz = time_sign_sz + time_days_sz + hours_sz + mins_sz + secs_sz;
|
||||
constexpr std::size_t time_dhmsu_sz = time_dhms_sz + micros_sz;
|
||||
|
||||
constexpr std::size_t time_max_days = 34; // equivalent to the 839 hours, in the broken format
|
||||
constexpr std::size_t time_max_days = 34; // equivalent to the 839 hours, in the broken format
|
||||
|
||||
} // binc
|
||||
} // namespace binc
|
||||
|
||||
// Constants common to both protocols
|
||||
constexpr unsigned max_year = 9999;
|
||||
@@ -166,10 +167,8 @@ constexpr unsigned max_min = 59;
|
||||
constexpr unsigned max_sec = 59;
|
||||
constexpr unsigned max_micro = 999999;
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
// All these algorithms have been taken from:
|
||||
// http://howardhinnant.github.io/date_algorithms.html
|
||||
|
||||
#include <cstdint>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
@@ -29,9 +30,9 @@ BOOST_CXX14_CONSTEXPR inline bool is_valid(const year_month_day& ymd) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline int ymd_to_days(const year_month_day& ymd) noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline year_month_day days_to_ymd(int num_days) noexcept;
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/protocol/impl/date.hpp>
|
||||
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
|
||||
#include <boost/mysql/detail/protocol/capabilities.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -24,19 +26,35 @@ class deserialization_context
|
||||
const std::uint8_t* first_;
|
||||
const std::uint8_t* last_;
|
||||
capabilities capabilities_;
|
||||
|
||||
public:
|
||||
deserialization_context(const std::uint8_t* first, const std::uint8_t* last, capabilities caps) noexcept:
|
||||
first_(first), last_(last), capabilities_(caps) { assert(last_ >= first_); };
|
||||
deserialization_context(boost::asio::const_buffer buff, capabilities caps) noexcept:
|
||||
deserialization_context(
|
||||
static_cast<const std::uint8_t*>(buff.data()),
|
||||
static_cast<const std::uint8_t*>(buff.data()) + buff.size(),
|
||||
caps
|
||||
) {};
|
||||
deserialization_context(
|
||||
const std::uint8_t* first,
|
||||
const std::uint8_t* last,
|
||||
capabilities caps
|
||||
) noexcept
|
||||
: first_(first), last_(last), capabilities_(caps)
|
||||
{
|
||||
assert(last_ >= first_);
|
||||
};
|
||||
deserialization_context(boost::asio::const_buffer buff, capabilities caps) noexcept
|
||||
: deserialization_context(
|
||||
static_cast<const std::uint8_t*>(buff.data()),
|
||||
static_cast<const std::uint8_t*>(buff.data()) + buff.size(),
|
||||
caps
|
||||
){};
|
||||
const std::uint8_t* first() const noexcept { return first_; }
|
||||
const std::uint8_t* last() const noexcept { return last_; }
|
||||
void set_first(const std::uint8_t* new_first) noexcept { first_ = new_first; assert(last_ >= first_); }
|
||||
void advance(std::size_t sz) noexcept { first_ += sz; assert(last_ >= first_); }
|
||||
void set_first(const std::uint8_t* new_first) noexcept
|
||||
{
|
||||
first_ = new_first;
|
||||
assert(last_ >= first_);
|
||||
}
|
||||
void advance(std::size_t sz) noexcept
|
||||
{
|
||||
first_ += sz;
|
||||
assert(last_ >= first_);
|
||||
}
|
||||
void rewind(std::size_t sz) noexcept { first_ -= sz; }
|
||||
std::size_t size() const noexcept { return last_ - first_; }
|
||||
bool empty() const noexcept { return last_ == first_; }
|
||||
@@ -52,10 +70,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_PROTOCOL_DESERIALIZATION_CONTEXT_HPP_ */
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/metadata.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
@@ -26,9 +27,9 @@ inline errc deserialize_binary_field(
|
||||
field_view& output
|
||||
);
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/protocol/impl/deserialize_binary_field.ipp>
|
||||
|
||||
|
||||
@@ -8,15 +8,16 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_PROTOCOL_DESERIALIZE_ROW_HPP
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_DESERIALIZE_ROW_HPP
|
||||
|
||||
#include <boost/mysql/detail/protocol/resultset_encoding.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/mysql/detail/protocol/capabilities.hpp>
|
||||
#include <boost/mysql/detail/protocol/resultset_encoding.hpp>
|
||||
#include <boost/mysql/detail/protocol/serialization_context.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <vector>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -32,13 +33,12 @@ inline void deserialize_row(
|
||||
error_code& err
|
||||
);
|
||||
|
||||
|
||||
inline void deserialize_row(
|
||||
boost::asio::const_buffer read_message,
|
||||
capabilities current_capabilities,
|
||||
const std::uint8_t* buffer_first, // to store strings as offsets and allow buffer reallocation
|
||||
resultset_base& result, // should be valid() and !complete()
|
||||
std::vector<field_view>& output,
|
||||
const std::uint8_t* buffer_first, // to store strings as offsets and allow buffer reallocation
|
||||
resultset_base& result, // should be valid() and !complete()
|
||||
std::vector<field_view>& output,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
);
|
||||
@@ -48,16 +48,14 @@ inline void offsets_to_string_views(
|
||||
const std::uint8_t* buffer_first
|
||||
) noexcept
|
||||
{
|
||||
for (auto& f: fields)
|
||||
for (auto& f : fields)
|
||||
f.offset_to_string_view(buffer_first);
|
||||
}
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/protocol/impl/deserialize_row.ipp>
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/metadata.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
@@ -26,9 +27,9 @@ inline errc deserialize_text_field(
|
||||
field_view& output
|
||||
);
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/protocol/impl/deserialize_text_field.ipp>
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_PROTOCOL_HANDSHAKE_MESSAGES_HPP
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_HANDSHAKE_MESSAGES_HPP
|
||||
|
||||
#include <boost/mysql/detail/protocol/serialization.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/static_string.hpp>
|
||||
#include <boost/mysql/detail/protocol/serialization.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -23,15 +23,16 @@ struct handshake_packet
|
||||
// int<1> protocol version Always 10
|
||||
string_null server_version;
|
||||
std::uint32_t connection_id;
|
||||
auth_buffer_type auth_plugin_data; // not an actual protocol field, the merge of two fields
|
||||
std::uint32_t capability_falgs; // merge of the two parts - not an actual field
|
||||
std::uint8_t character_set; // default server a_protocol_character_set, only the lower 8-bits
|
||||
std::uint16_t status_flags; // server_status_flags
|
||||
auth_buffer_type auth_plugin_data; // not an actual protocol field, the merge of two fields
|
||||
std::uint32_t capability_falgs; // merge of the two parts - not an actual field
|
||||
std::uint8_t character_set; // default server a_protocol_character_set, only the lower 8-bits
|
||||
std::uint16_t status_flags; // server_status_flags
|
||||
string_null auth_plugin_name;
|
||||
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
// clang-format off
|
||||
std::forward<Callable>(cb)(
|
||||
self.server_version,
|
||||
self.connection_id,
|
||||
@@ -41,52 +42,60 @@ struct handshake_packet
|
||||
self.status_flags,
|
||||
self.auth_plugin_name
|
||||
);
|
||||
// clang-format on
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct serialization_traits<handshake_packet, serialization_tag::struct_with_fields> :
|
||||
noop_serialize<handshake_packet>
|
||||
struct serialization_traits<handshake_packet, serialization_tag::struct_with_fields>
|
||||
: noop_serialize<handshake_packet>
|
||||
{
|
||||
static inline errc deserialize_(deserialization_context& ctx, handshake_packet& output) noexcept;
|
||||
static inline errc deserialize_(
|
||||
deserialization_context& ctx,
|
||||
handshake_packet& output
|
||||
) noexcept;
|
||||
};
|
||||
|
||||
// response
|
||||
struct handshake_response_packet
|
||||
{
|
||||
std::uint32_t client_flag; // capabilities
|
||||
std::uint32_t client_flag; // capabilities
|
||||
std::uint32_t max_packet_size;
|
||||
std::uint8_t character_set;
|
||||
// string[23] filler filler to the size of the handhshake response packet. All 0s.
|
||||
string_null username;
|
||||
string_lenenc auth_response; // we require CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA
|
||||
string_null database; // only to be serialized if CLIENT_CONNECT_WITH_DB
|
||||
string_null client_plugin_name; // we require CLIENT_PLUGIN_AUTH
|
||||
string_lenenc auth_response; // we require CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA
|
||||
string_null database; // only to be serialized if CLIENT_CONNECT_WITH_DB
|
||||
string_null client_plugin_name; // we require CLIENT_PLUGIN_AUTH
|
||||
// CLIENT_CONNECT_ATTRS: not implemented
|
||||
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
std::forward<Callable>(cb)(
|
||||
self.client_flag,
|
||||
self.max_packet_size,
|
||||
self.character_set,
|
||||
self.username,
|
||||
self.auth_response,
|
||||
self.database,
|
||||
self.client_plugin_name
|
||||
);
|
||||
std::forward<Callable>(cb
|
||||
)(self.client_flag,
|
||||
self.max_packet_size,
|
||||
self.character_set,
|
||||
self.username,
|
||||
self.auth_response,
|
||||
self.database,
|
||||
self.client_plugin_name);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct serialization_traits<handshake_response_packet, serialization_tag::struct_with_fields> :
|
||||
noop_deserialize<handshake_response_packet>
|
||||
struct serialization_traits<handshake_response_packet, serialization_tag::struct_with_fields>
|
||||
: noop_deserialize<handshake_response_packet>
|
||||
{
|
||||
static inline std::size_t get_size_(const serialization_context& ctx,
|
||||
const handshake_response_packet& value) noexcept;
|
||||
static inline void serialize_(serialization_context& ctx,
|
||||
const handshake_response_packet& value) noexcept;
|
||||
static inline std::size_t get_size_(
|
||||
const serialization_context& ctx,
|
||||
const handshake_response_packet& value
|
||||
) noexcept;
|
||||
|
||||
static inline void serialize_(
|
||||
serialization_context& ctx,
|
||||
const handshake_response_packet& value
|
||||
) noexcept;
|
||||
};
|
||||
|
||||
// SSL request
|
||||
@@ -100,12 +109,14 @@ struct ssl_request
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
// clang-format off
|
||||
std::forward<Callable>(cb)(
|
||||
self.client_flag,
|
||||
self.max_packet_size,
|
||||
self.character_set,
|
||||
self.filler
|
||||
);
|
||||
// clang-format on
|
||||
}
|
||||
};
|
||||
|
||||
@@ -118,10 +129,7 @@ struct auth_switch_request_packet
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
std::forward<Callable>(cb)(
|
||||
self.plugin_name,
|
||||
self.auth_plugin_data
|
||||
);
|
||||
std::forward<Callable>(cb)(self.plugin_name, self.auth_plugin_data);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -133,18 +141,18 @@ struct auth_switch_response_packet
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
std::forward<Callable>(cb)(
|
||||
self.auth_plugin_data
|
||||
);
|
||||
std::forward<Callable>(cb)(self.auth_plugin_data);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct serialization_traits<auth_switch_request_packet, serialization_tag::struct_with_fields> :
|
||||
noop_serialize<auth_switch_request_packet>
|
||||
struct serialization_traits<auth_switch_request_packet, serialization_tag::struct_with_fields>
|
||||
: noop_serialize<auth_switch_request_packet>
|
||||
{
|
||||
static inline errc deserialize_(deserialization_context& ctx,
|
||||
auth_switch_request_packet& output) noexcept;
|
||||
static inline errc deserialize_(
|
||||
deserialization_context& ctx,
|
||||
auth_switch_request_packet& output
|
||||
) noexcept;
|
||||
};
|
||||
|
||||
// more data (like auth switch request, but for the same plugin)
|
||||
@@ -155,15 +163,13 @@ struct auth_more_data_packet
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
std::forward<Callable>(cb)(
|
||||
self.auth_plugin_data
|
||||
);
|
||||
std::forward<Callable>(cb)(self.auth_plugin_data);
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/protocol/impl/handshake_messages.ipp>
|
||||
|
||||
|
||||
@@ -20,23 +20,16 @@ namespace detail {
|
||||
|
||||
// Floating point types
|
||||
template <class T>
|
||||
void serialize_binary_float(
|
||||
serialization_context& ctx,
|
||||
T input
|
||||
)
|
||||
void serialize_binary_float(serialization_context& ctx, T input)
|
||||
{
|
||||
boost::endian::endian_store<T, sizeof(T),
|
||||
boost::endian::order::little>(ctx.first(), input);
|
||||
boost::endian::endian_store<T, sizeof(T), boost::endian::order::little>(ctx.first(), input);
|
||||
ctx.advance(sizeof(T));
|
||||
}
|
||||
|
||||
// Time types
|
||||
|
||||
// Does not add the length prefix byte
|
||||
inline void serialize_binary_ymd(
|
||||
serialization_context& ctx,
|
||||
const year_month_day& ymd
|
||||
) noexcept
|
||||
inline void serialize_binary_ymd(serialization_context& ctx, const year_month_day& ymd) noexcept
|
||||
{
|
||||
assert(ymd.years >= 0 && ymd.years <= 0xffff);
|
||||
serialize(
|
||||
@@ -47,10 +40,7 @@ inline void serialize_binary_ymd(
|
||||
);
|
||||
}
|
||||
|
||||
inline void serialize_binary_date(
|
||||
serialization_context& ctx,
|
||||
const date& input
|
||||
)
|
||||
inline void serialize_binary_date(serialization_context& ctx, const date& input)
|
||||
{
|
||||
assert(input >= min_date && input <= max_date);
|
||||
auto ymd = days_to_ymd(input.time_since_epoch().count());
|
||||
@@ -59,10 +49,7 @@ inline void serialize_binary_date(
|
||||
serialize_binary_ymd(ctx, ymd);
|
||||
}
|
||||
|
||||
inline void serialize_binary_datetime(
|
||||
serialization_context& ctx,
|
||||
const datetime& input
|
||||
)
|
||||
inline void serialize_binary_datetime(serialization_context& ctx, const datetime& input)
|
||||
{
|
||||
assert(input >= min_datetime && input <= max_datetime);
|
||||
|
||||
@@ -87,10 +74,7 @@ inline void serialize_binary_datetime(
|
||||
);
|
||||
}
|
||||
|
||||
inline void serialize_binary_time(
|
||||
serialization_context& ctx,
|
||||
const time& input
|
||||
)
|
||||
inline void serialize_binary_time(serialization_context& ctx, const time& input)
|
||||
{
|
||||
// Break time
|
||||
using namespace std::chrono;
|
||||
@@ -114,54 +98,43 @@ inline void serialize_binary_time(
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
inline std::size_t
|
||||
boost::mysql::detail::serialization_traits<
|
||||
boost::mysql::field_view,
|
||||
boost::mysql::detail::serialization_tag::none
|
||||
>::get_size_(
|
||||
const serialization_context& ctx,
|
||||
const field_view& input
|
||||
) noexcept
|
||||
inline std::size_t boost::mysql::detail::
|
||||
serialization_traits<boost::mysql::field_view, boost::mysql::detail::serialization_tag::none>::
|
||||
get_size_(const serialization_context& ctx, const field_view& input) noexcept
|
||||
{
|
||||
switch (input.kind())
|
||||
{
|
||||
case field_kind::null: return 0;
|
||||
case field_kind::int64: return 8;
|
||||
case field_kind::uint64: return 8;
|
||||
case field_kind::string: return get_size(ctx, string_lenenc(input.get_string()));
|
||||
case field_kind::float_: return 4;
|
||||
case field_kind::double_: return 8;
|
||||
case field_kind::date: return binc::date_sz + binc::length_sz;
|
||||
case field_kind::datetime: return binc::datetime_dhmsu_sz + binc::length_sz;
|
||||
case field_kind::time: return binc::time_dhmsu_sz + binc::length_sz;
|
||||
case field_kind::null: return 0;
|
||||
case field_kind::int64: return 8;
|
||||
case field_kind::uint64: return 8;
|
||||
case field_kind::string: return get_size(ctx, string_lenenc(input.get_string()));
|
||||
case field_kind::float_: return 4;
|
||||
case field_kind::double_: return 8;
|
||||
case field_kind::date: return binc::date_sz + binc::length_sz;
|
||||
case field_kind::datetime: return binc::datetime_dhmsu_sz + binc::length_sz;
|
||||
case field_kind::time: return binc::time_dhmsu_sz + binc::length_sz;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
boost::mysql::detail::serialization_traits<
|
||||
boost::mysql::field_view,
|
||||
boost::mysql::detail::serialization_tag::none
|
||||
>::serialize_(
|
||||
serialization_context& ctx,
|
||||
const field_view& input
|
||||
) noexcept
|
||||
inline void boost::mysql::detail::
|
||||
serialization_traits<boost::mysql::field_view, boost::mysql::detail::serialization_tag::none>::
|
||||
serialize_(serialization_context& ctx, const field_view& input) noexcept
|
||||
{
|
||||
switch (input.kind())
|
||||
{
|
||||
case field_kind::null: break;
|
||||
case field_kind::int64: serialize(ctx, input.get_int64()); break;
|
||||
case field_kind::uint64: serialize(ctx, input.get_uint64()); break;
|
||||
case field_kind::string: serialize(ctx, string_lenenc(input.get_string())); break;
|
||||
case field_kind::float_: serialize_binary_float(ctx, input.get_float()); break;
|
||||
case field_kind::double_: serialize_binary_float(ctx, input.get_double()); break;
|
||||
case field_kind::date: serialize_binary_date(ctx, input.get_date()); break;
|
||||
case field_kind::datetime: serialize_binary_datetime(ctx, input.get_datetime()); break;
|
||||
case field_kind::time: serialize_binary_time(ctx, input.get_time()); break;
|
||||
case field_kind::null: break;
|
||||
case field_kind::int64: serialize(ctx, input.get_int64()); break;
|
||||
case field_kind::uint64: serialize(ctx, input.get_uint64()); break;
|
||||
case field_kind::string: serialize(ctx, string_lenenc(input.get_string())); break;
|
||||
case field_kind::float_: serialize_binary_float(ctx, input.get_float()); break;
|
||||
case field_kind::double_: serialize_binary_float(ctx, input.get_double()); break;
|
||||
case field_kind::date: serialize_binary_date(ctx, input.get_date()); break;
|
||||
case field_kind::datetime: serialize_binary_datetime(ctx, input.get_datetime()); break;
|
||||
case field_kind::time: serialize_binary_time(ctx, input.get_time()); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,15 +12,10 @@
|
||||
|
||||
#include <boost/mysql/detail/protocol/common_messages.hpp>
|
||||
|
||||
|
||||
inline boost::mysql::errc
|
||||
boost::mysql::detail::serialization_traits<
|
||||
inline boost::mysql::errc boost::mysql::detail::serialization_traits<
|
||||
boost::mysql::detail::ok_packet,
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields
|
||||
>::deserialize_(
|
||||
deserialization_context& ctx,
|
||||
ok_packet& output
|
||||
) noexcept
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields>::
|
||||
deserialize_(deserialization_context& ctx, ok_packet& output) noexcept
|
||||
{
|
||||
{
|
||||
auto err = deserialize(
|
||||
@@ -30,7 +25,7 @@ boost::mysql::detail::serialization_traits<
|
||||
output.status_flags,
|
||||
output.warnings
|
||||
);
|
||||
if (err == errc::ok && ctx.enough_size(1)) // message is optional, may be omitted
|
||||
if (err == errc::ok && ctx.enough_size(1)) // message is optional, may be omitted
|
||||
{
|
||||
err = deserialize(ctx, output.info);
|
||||
}
|
||||
@@ -38,14 +33,10 @@ boost::mysql::detail::serialization_traits<
|
||||
}
|
||||
}
|
||||
|
||||
inline boost::mysql::errc
|
||||
boost::mysql::detail::serialization_traits<
|
||||
inline boost::mysql::errc boost::mysql::detail::serialization_traits<
|
||||
boost::mysql::detail::column_definition_packet,
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields
|
||||
>::deserialize_(
|
||||
deserialization_context& ctx,
|
||||
column_definition_packet& output
|
||||
) noexcept
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields>::
|
||||
deserialize_(deserialization_context& ctx, column_definition_packet& output) noexcept
|
||||
{
|
||||
int_lenenc length_of_fixed_fields;
|
||||
std::uint16_t final_padding = 0;
|
||||
@@ -67,12 +58,10 @@ boost::mysql::detail::serialization_traits<
|
||||
);
|
||||
}
|
||||
|
||||
inline boost::mysql::error_code boost::mysql::detail::process_error_packet(
|
||||
deserialization_context& ctx,
|
||||
error_info& info
|
||||
)
|
||||
inline boost::mysql::error_code
|
||||
boost::mysql::detail::process_error_packet(deserialization_context& ctx, error_info& info)
|
||||
{
|
||||
err_packet error_packet {};
|
||||
err_packet error_packet{};
|
||||
auto code = deserialize_message(ctx, error_packet);
|
||||
if (code)
|
||||
return code;
|
||||
@@ -80,5 +69,4 @@ inline boost::mysql::error_code boost::mysql::detail::process_error_packet(
|
||||
return make_error_code(static_cast<errc>(error_packet.error_code));
|
||||
}
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_PROTOCOL_IMPL_COMMON_MESSAGES_IPP_ */
|
||||
|
||||
@@ -10,45 +10,34 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/protocol/date.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
#include <boost/mysql/detail/protocol/date.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
constexpr bool is_leap(int y) noexcept
|
||||
{
|
||||
return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
|
||||
}
|
||||
constexpr bool is_leap(int y) noexcept { return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0); }
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline unsigned last_month_day(int y, unsigned m) noexcept
|
||||
{
|
||||
constexpr unsigned char a [] =
|
||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
return m != 2 || !is_leap(y) ? a[m-1] : 29u;
|
||||
constexpr unsigned char a[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
return m != 2 || !is_leap(y) ? a[m - 1] : 29u;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline bool boost::mysql::detail::is_valid(
|
||||
const year_month_day& ymd
|
||||
) noexcept
|
||||
BOOST_CXX14_CONSTEXPR inline bool boost::mysql::detail::is_valid(const year_month_day& ymd) noexcept
|
||||
{
|
||||
return
|
||||
ymd.years >= 0 &&
|
||||
ymd.years <= static_cast<int>(max_year) &&
|
||||
ymd.month > 0 &&
|
||||
ymd.month <= max_month &&
|
||||
ymd.day > 0 &&
|
||||
ymd.day <= last_month_day(ymd.years, ymd.month);
|
||||
return ymd.years >= 0 && ymd.years <= static_cast<int>(max_year) && ymd.month > 0 &&
|
||||
ymd.month <= max_month && ymd.day > 0 && ymd.day <= last_month_day(ymd.years, ymd.month);
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int boost::mysql::detail::ymd_to_days(
|
||||
const year_month_day& ymd
|
||||
BOOST_CXX14_CONSTEXPR inline int boost::mysql::detail::ymd_to_days(const year_month_day& ymd
|
||||
) noexcept
|
||||
{
|
||||
assert(is_valid(ymd));
|
||||
@@ -56,32 +45,27 @@ BOOST_CXX14_CONSTEXPR inline int boost::mysql::detail::ymd_to_days(
|
||||
const int m = ymd.month;
|
||||
const int d = ymd.day;
|
||||
y -= m <= 2;
|
||||
const int era = (y >= 0 ? y : y-399) / 400;
|
||||
const unsigned yoe = static_cast<unsigned>(y - era * 400); // [0, 399]
|
||||
const unsigned doy = (153*(m + (m > 2 ? -3 : 9)) + 2)/5 + d-1; // [0, 365]
|
||||
const unsigned doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096]
|
||||
const int era = (y >= 0 ? y : y - 399) / 400;
|
||||
const unsigned yoe = static_cast<unsigned>(y - era * 400); // [0, 399]
|
||||
const unsigned doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1; // [0, 365]
|
||||
const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096]
|
||||
return era * 146097 + static_cast<int>(doe) - 719468;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::mysql::detail::year_month_day
|
||||
boost::mysql::detail::days_to_ymd(
|
||||
BOOST_CXX14_CONSTEXPR inline boost::mysql::detail::year_month_day boost::mysql::detail::days_to_ymd(
|
||||
int num_days
|
||||
) noexcept
|
||||
{
|
||||
num_days += 719468;
|
||||
const int era = (num_days >= 0 ? num_days : num_days - 146096) / 146097;
|
||||
const unsigned doe = static_cast<unsigned>(num_days - era * 146097); // [0, 146096]
|
||||
const unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399]
|
||||
const unsigned doe = static_cast<unsigned>(num_days - era * 146097); // [0, 146096]
|
||||
const unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399]
|
||||
const int y = static_cast<int>(yoe) + era * 400;
|
||||
const unsigned doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365]
|
||||
const unsigned mp = (5*doy + 2)/153; // [0, 11]
|
||||
const unsigned d = doy - (153*mp+2)/5 + 1; // [1, 31]
|
||||
const unsigned m = mp + (mp < 10 ? 3 : -9); // [1, 12]
|
||||
const unsigned doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365]
|
||||
const unsigned mp = (5 * doy + 2) / 153; // [0, 11]
|
||||
const unsigned d = doy - (153 * mp + 2) / 5 + 1; // [1, 31]
|
||||
const unsigned m = mp + (mp < 10 ? 3 : -9); // [1, 12]
|
||||
return year_month_day{y + (m <= 2), m, d};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,11 +11,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/auxiliar/string_view_offset.hpp>
|
||||
#include <boost/mysql/detail/protocol/deserialize_binary_field.hpp>
|
||||
#include <boost/mysql/detail/protocol/serialization.hpp>
|
||||
#include <boost/mysql/detail/protocol/bit_deserialization.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
#include <boost/mysql/detail/protocol/date.hpp>
|
||||
#include <boost/mysql/detail/protocol/bit_deserialization.hpp>
|
||||
#include <boost/mysql/detail/protocol/deserialize_binary_field.hpp>
|
||||
#include <boost/mysql/detail/protocol/serialization.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
@@ -39,10 +40,7 @@ inline errc deserialize_binary_field_string(
|
||||
|
||||
// ints
|
||||
template <class TargetType, class DeserializableType>
|
||||
errc deserialize_binary_field_int_impl(
|
||||
deserialization_context& ctx,
|
||||
field_view& output
|
||||
) noexcept
|
||||
errc deserialize_binary_field_int_impl(deserialization_context& ctx, field_view& output) noexcept
|
||||
{
|
||||
DeserializableType deser;
|
||||
auto err = deserialize(ctx, deser);
|
||||
@@ -52,50 +50,45 @@ errc deserialize_binary_field_int_impl(
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
template <
|
||||
class DeserializableTypeUnsigned,
|
||||
class DeserializableTypeSigned
|
||||
>
|
||||
template <class DeserializableTypeUnsigned, class DeserializableTypeSigned>
|
||||
errc deserialize_binary_field_int(
|
||||
const metadata& meta,
|
||||
deserialization_context& ctx,
|
||||
field_view& output
|
||||
) noexcept
|
||||
{
|
||||
return meta.is_unsigned() ?
|
||||
deserialize_binary_field_int_impl<
|
||||
std::uint64_t, DeserializableTypeUnsigned>(ctx, output) :
|
||||
deserialize_binary_field_int_impl<
|
||||
std::int64_t, DeserializableTypeSigned>(ctx, output);
|
||||
return meta.is_unsigned()
|
||||
? deserialize_binary_field_int_impl<std::uint64_t, DeserializableTypeUnsigned>(
|
||||
ctx,
|
||||
output
|
||||
)
|
||||
: deserialize_binary_field_int_impl<std::int64_t, DeserializableTypeSigned>(
|
||||
ctx,
|
||||
output
|
||||
);
|
||||
}
|
||||
|
||||
// Bits. These come as a binary value between 1 and 8 bytes,
|
||||
// packed in a string
|
||||
inline errc deserialize_binary_field_bit(
|
||||
deserialization_context& ctx,
|
||||
field_view& output
|
||||
) noexcept
|
||||
inline errc deserialize_binary_field_bit(deserialization_context& ctx, field_view& output) noexcept
|
||||
{
|
||||
string_lenenc buffer;
|
||||
auto err = deserialize(ctx, buffer);
|
||||
if (err != errc::ok) return err;
|
||||
if (err != errc::ok)
|
||||
return err;
|
||||
return deserialize_bit(buffer.value, output);
|
||||
}
|
||||
|
||||
// Floats
|
||||
template <class T>
|
||||
errc deserialize_binary_field_float(
|
||||
deserialization_context& ctx,
|
||||
field_view& output
|
||||
) noexcept
|
||||
errc deserialize_binary_field_float(deserialization_context& ctx, field_view& output) noexcept
|
||||
{
|
||||
// Size check
|
||||
if (!ctx.enough_size(sizeof(T)))
|
||||
return errc::incomplete_message;
|
||||
|
||||
// Endianness conversion. Boost.Endian support for floats start at 1.71
|
||||
T v = boost::endian::endian_load<T, sizeof(T),
|
||||
boost::endian::order::little>(ctx.first());
|
||||
T v = boost::endian::endian_load<T, sizeof(T), boost::endian::order::little>(ctx.first());
|
||||
|
||||
// Nans and infs not allowed in SQL
|
||||
if (std::isnan(v) || std::isinf(v))
|
||||
@@ -108,10 +101,7 @@ errc deserialize_binary_field_float(
|
||||
}
|
||||
|
||||
// Time types
|
||||
inline errc deserialize_binary_ymd(
|
||||
deserialization_context& ctx,
|
||||
year_month_day& output
|
||||
)
|
||||
inline errc deserialize_binary_ymd(deserialization_context& ctx, year_month_day& output)
|
||||
{
|
||||
std::uint16_t year;
|
||||
std::uint8_t month;
|
||||
@@ -123,22 +113,17 @@ inline errc deserialize_binary_ymd(
|
||||
return err;
|
||||
|
||||
// Range check
|
||||
if (year > max_year ||
|
||||
month > max_month ||
|
||||
day > max_day)
|
||||
if (year > max_year || month > max_month || day > max_day)
|
||||
{
|
||||
return errc::protocol_value_error;
|
||||
}
|
||||
|
||||
output = year_month_day {year, month, day};
|
||||
output = year_month_day{year, month, day};
|
||||
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
inline errc deserialize_binary_field_date(
|
||||
deserialization_context& ctx,
|
||||
field_view& output
|
||||
) noexcept
|
||||
inline errc deserialize_binary_field_date(deserialization_context& ctx, field_view& output) noexcept
|
||||
{
|
||||
// Deserialize length
|
||||
std::uint8_t length;
|
||||
@@ -171,10 +156,8 @@ inline errc deserialize_binary_field_date(
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
inline errc deserialize_binary_field_datetime(
|
||||
deserialization_context& ctx,
|
||||
field_view& output
|
||||
) noexcept
|
||||
inline errc
|
||||
deserialize_binary_field_datetime(deserialization_context& ctx, field_view& output) noexcept
|
||||
{
|
||||
using namespace binc;
|
||||
|
||||
@@ -186,7 +169,7 @@ inline errc deserialize_binary_field_datetime(
|
||||
|
||||
// Deserialize date. If the DATETIME does not contain these values,
|
||||
// they are supposed to be zero (invalid date)
|
||||
year_month_day ymd {};
|
||||
year_month_day ymd{};
|
||||
if (length >= datetime_d_sz)
|
||||
{
|
||||
err = deserialize_binary_ymd(ctx, ymd);
|
||||
@@ -219,10 +202,7 @@ inline errc deserialize_binary_field_datetime(
|
||||
// Validity check. We make this check before
|
||||
// the invalid date check to make invalid dates with incorrect
|
||||
// hours/mins/secs/micros fail
|
||||
if (hours > max_hour ||
|
||||
minutes > max_min ||
|
||||
seconds > max_sec ||
|
||||
micros > max_micro)
|
||||
if (hours > max_hour || minutes > max_min || seconds > max_sec || micros > max_micro)
|
||||
{
|
||||
return errc::protocol_value_error;
|
||||
}
|
||||
@@ -237,20 +217,14 @@ inline errc deserialize_binary_field_datetime(
|
||||
}
|
||||
|
||||
// Compose the final datetime. Doing time of day and date separately to avoid overflow
|
||||
date d (days(ymd_to_days(ymd)));
|
||||
auto time_of_day =
|
||||
std::chrono::hours(hours) +
|
||||
std::chrono::minutes(minutes) +
|
||||
std::chrono::seconds(seconds) +
|
||||
std::chrono::microseconds(micros);
|
||||
date d(days(ymd_to_days(ymd)));
|
||||
auto time_of_day = std::chrono::hours(hours) + std::chrono::minutes(minutes) +
|
||||
std::chrono::seconds(seconds) + std::chrono::microseconds(micros);
|
||||
output = field_view(d + time_of_day);
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
inline errc deserialize_binary_field_time(
|
||||
deserialization_context& ctx,
|
||||
field_view& output
|
||||
) noexcept
|
||||
inline errc deserialize_binary_field_time(deserialization_context& ctx, field_view& output) noexcept
|
||||
{
|
||||
using namespace binc;
|
||||
|
||||
@@ -271,14 +245,7 @@ inline errc deserialize_binary_field_time(
|
||||
// Sign, days, hours, minutes, seconds
|
||||
if (length >= time_dhms_sz)
|
||||
{
|
||||
err = deserialize(
|
||||
ctx,
|
||||
is_negative,
|
||||
num_days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds
|
||||
);
|
||||
err = deserialize(ctx, is_negative, num_days, hours, minutes, seconds);
|
||||
if (err != errc::ok)
|
||||
return err;
|
||||
}
|
||||
@@ -292,30 +259,24 @@ inline errc deserialize_binary_field_time(
|
||||
}
|
||||
|
||||
// Range check
|
||||
if (num_days > time_max_days ||
|
||||
hours > max_hour ||
|
||||
minutes > max_min ||
|
||||
seconds > max_sec ||
|
||||
if (num_days > time_max_days || hours > max_hour || minutes > max_min || seconds > max_sec ||
|
||||
microseconds > max_micro)
|
||||
{
|
||||
return errc::protocol_value_error;
|
||||
}
|
||||
|
||||
// Compose the final time
|
||||
output = field_view(time((is_negative ? -1 : 1) * (
|
||||
days(num_days) +
|
||||
std::chrono::hours(hours) +
|
||||
std::chrono::minutes(minutes) +
|
||||
std::chrono::seconds(seconds) +
|
||||
std::chrono::microseconds(microseconds)
|
||||
)));
|
||||
output = field_view(time(
|
||||
(is_negative ? -1 : 1) *
|
||||
(days(num_days) + std::chrono::hours(hours) + std::chrono::minutes(minutes) +
|
||||
std::chrono::seconds(seconds) + std::chrono::microseconds(microseconds))
|
||||
));
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
inline boost::mysql::errc boost::mysql::detail::deserialize_binary_field(
|
||||
deserialization_context& ctx,
|
||||
@@ -336,19 +297,13 @@ inline boost::mysql::errc boost::mysql::detail::deserialize_binary_field(
|
||||
return deserialize_binary_field_int<std::uint32_t, std::int32_t>(meta, ctx, output);
|
||||
case protocol_field_type::longlong:
|
||||
return deserialize_binary_field_int<std::uint64_t, std::int64_t>(meta, ctx, output);
|
||||
case protocol_field_type::bit:
|
||||
return deserialize_binary_field_bit(ctx, output);
|
||||
case protocol_field_type::float_:
|
||||
return deserialize_binary_field_float<float>(ctx, output);
|
||||
case protocol_field_type::double_:
|
||||
return deserialize_binary_field_float<double>(ctx, output);
|
||||
case protocol_field_type::bit: return deserialize_binary_field_bit(ctx, output);
|
||||
case protocol_field_type::float_: return deserialize_binary_field_float<float>(ctx, output);
|
||||
case protocol_field_type::double_: return deserialize_binary_field_float<double>(ctx, output);
|
||||
case protocol_field_type::timestamp:
|
||||
case protocol_field_type::datetime:
|
||||
return deserialize_binary_field_datetime(ctx, output);
|
||||
case protocol_field_type::date:
|
||||
return deserialize_binary_field_date(ctx, output);
|
||||
case protocol_field_type::time:
|
||||
return deserialize_binary_field_time(ctx, output);
|
||||
case protocol_field_type::datetime: return deserialize_binary_field_datetime(ctx, output);
|
||||
case protocol_field_type::date: return deserialize_binary_field_date(ctx, output);
|
||||
case protocol_field_type::time: return deserialize_binary_field_time(ctx, output);
|
||||
// True string types
|
||||
case protocol_field_type::varchar:
|
||||
case protocol_field_type::var_string:
|
||||
@@ -363,8 +318,7 @@ inline boost::mysql::errc boost::mysql::detail::deserialize_binary_field(
|
||||
case protocol_field_type::decimal:
|
||||
case protocol_field_type::newdecimal:
|
||||
case protocol_field_type::geometry:
|
||||
default:
|
||||
return deserialize_binary_field_string(ctx, output, buffer_first);
|
||||
default: return deserialize_binary_field_string(ctx, output, buffer_first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,19 +10,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/protocol/deserialize_binary_field.hpp>
|
||||
#include <boost/mysql/detail/protocol/deserialize_row.hpp>
|
||||
#include <boost/mysql/detail/protocol/deserialize_text_field.hpp>
|
||||
#include <boost/mysql/detail/protocol/null_bitmap_traits.hpp>
|
||||
#include <boost/mysql/detail/protocol/deserialize_binary_field.hpp>
|
||||
#include <boost/mysql/detail/protocol/serialization.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
inline bool is_next_field_null(
|
||||
const deserialization_context& ctx
|
||||
)
|
||||
inline bool is_next_field_null(const deserialization_context& ctx)
|
||||
{
|
||||
if (!ctx.enough_size(1))
|
||||
return false;
|
||||
@@ -54,7 +52,12 @@ inline error_code deserialize_text_row(
|
||||
errc err = deserialize(ctx, value_str);
|
||||
if (err != errc::ok)
|
||||
return make_error_code(err);
|
||||
err = deserialize_text_field(value_str.value, fields[i], buffer_first, output[old_size + i]);
|
||||
err = deserialize_text_field(
|
||||
value_str.value,
|
||||
fields[i],
|
||||
buffer_first,
|
||||
output[old_size + i]
|
||||
);
|
||||
if (err != errc::ok)
|
||||
return make_error_code(err);
|
||||
}
|
||||
@@ -64,7 +67,6 @@ inline error_code deserialize_text_row(
|
||||
return error_code();
|
||||
}
|
||||
|
||||
|
||||
inline error_code deserialize_binary_row(
|
||||
deserialization_context& ctx,
|
||||
const std::vector<metadata>& meta,
|
||||
@@ -84,7 +86,7 @@ inline error_code deserialize_binary_row(
|
||||
output.resize(old_size + num_fields);
|
||||
|
||||
// Null bitmap
|
||||
null_bitmap_traits null_bitmap (binary_row_null_bitmap_offset, num_fields);
|
||||
null_bitmap_traits null_bitmap(binary_row_null_bitmap_offset, num_fields);
|
||||
const std::uint8_t* null_bitmap_begin = ctx.first();
|
||||
if (!ctx.enough_size(null_bitmap.byte_count()))
|
||||
return make_error_code(errc::incomplete_message);
|
||||
@@ -112,9 +114,9 @@ inline error_code deserialize_binary_row(
|
||||
return error_code();
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
void boost::mysql::detail::deserialize_row(
|
||||
resultset_encoding encoding,
|
||||
@@ -125,17 +127,17 @@ void boost::mysql::detail::deserialize_row(
|
||||
error_code& err
|
||||
)
|
||||
{
|
||||
err = encoding == detail::resultset_encoding::text ?
|
||||
deserialize_text_row(ctx, meta, buffer_first, output) :
|
||||
deserialize_binary_row(ctx, meta, buffer_first, output);
|
||||
err = encoding == detail::resultset_encoding::text
|
||||
? deserialize_text_row(ctx, meta, buffer_first, output)
|
||||
: deserialize_binary_row(ctx, meta, buffer_first, output);
|
||||
}
|
||||
|
||||
void boost::mysql::detail::deserialize_row(
|
||||
boost::asio::const_buffer read_message,
|
||||
capabilities current_capabilities,
|
||||
const std::uint8_t* buffer_first, // to store strings as offsets and allow buffer reallocation
|
||||
const std::uint8_t* buffer_first, // to store strings as offsets and allow buffer reallocation
|
||||
resultset_base& result,
|
||||
std::vector<field_view>& output,
|
||||
std::vector<field_view>& output,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
@@ -145,7 +147,7 @@ void boost::mysql::detail::deserialize_row(
|
||||
|
||||
// Message type: row, error or eof?
|
||||
std::uint8_t msg_type = 0;
|
||||
deserialization_context ctx (read_message, current_capabilities);
|
||||
deserialization_context ctx(read_message, current_capabilities);
|
||||
err = make_error_code(deserialize(ctx, msg_type));
|
||||
if (err)
|
||||
return;
|
||||
@@ -166,7 +168,7 @@ void boost::mysql::detail::deserialize_row(
|
||||
else
|
||||
{
|
||||
// An actual row
|
||||
ctx.rewind(1); // keep the 'message type' byte, as it is part of the actual message
|
||||
ctx.rewind(1); // keep the 'message type' byte, as it is part of the actual message
|
||||
deserialize_row(result.encoding(), ctx, result.meta(), buffer_first, output, err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,21 +10,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/protocol/deserialize_text_field.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/string_view_offset.hpp>
|
||||
#include <boost/mysql/detail/protocol/bit_deserialization.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
#include <boost/mysql/detail/protocol/date.hpp>
|
||||
#include <boost/mysql/detail/protocol/bit_deserialization.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/string_view_offset.hpp>
|
||||
#include <boost/mysql/detail/protocol/deserialize_text_field.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/lexical_cast/try_lexical_convert.hpp>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4996 ) // MSVC doesn't like my sscanf's
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996) // MSVC doesn't like my sscanf's
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
@@ -33,10 +35,7 @@ namespace detail {
|
||||
|
||||
// Integers
|
||||
template <class T>
|
||||
errc deserialize_text_value_int_impl(
|
||||
boost::string_view from,
|
||||
field_view& to
|
||||
) noexcept
|
||||
errc deserialize_text_value_int_impl(boost::string_view from, field_view& to) noexcept
|
||||
{
|
||||
T v;
|
||||
bool ok = boost::conversion::try_lexical_convert(from.data(), from.size(), v);
|
||||
@@ -46,27 +45,20 @@ errc deserialize_text_value_int_impl(
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
inline errc deserialize_text_value_int(
|
||||
boost::string_view from,
|
||||
field_view& to,
|
||||
const metadata& meta
|
||||
) noexcept
|
||||
inline errc
|
||||
deserialize_text_value_int(boost::string_view from, field_view& to, const metadata& meta) noexcept
|
||||
{
|
||||
return meta.is_unsigned() ?
|
||||
deserialize_text_value_int_impl<std::uint64_t>(from, to) :
|
||||
deserialize_text_value_int_impl<std::int64_t>(from, to);
|
||||
return meta.is_unsigned() ? deserialize_text_value_int_impl<std::uint64_t>(from, to)
|
||||
: deserialize_text_value_int_impl<std::int64_t>(from, to);
|
||||
}
|
||||
|
||||
// Floating points
|
||||
template <class T>
|
||||
errc deserialize_text_value_float(
|
||||
boost::string_view from,
|
||||
field_view& to
|
||||
) noexcept
|
||||
errc deserialize_text_value_float(boost::string_view from, field_view& to) noexcept
|
||||
{
|
||||
T val;
|
||||
bool ok = boost::conversion::try_lexical_convert(from.data(), from.size(), val);
|
||||
if (!ok || std::isnan(val) || std::isinf(val)) // SQL std forbids these values
|
||||
if (!ok || std::isnan(val) || std::isinf(val)) // SQL std forbids these values
|
||||
return errc::protocol_value_error;
|
||||
to = field_view(val);
|
||||
return errc::ok;
|
||||
@@ -96,10 +88,7 @@ inline unsigned compute_micros(unsigned parsed_micros, unsigned decimals) noexce
|
||||
return parsed_micros * static_cast<unsigned>(std::pow(10, textc::max_decimals - decimals));
|
||||
}
|
||||
|
||||
inline errc deserialize_text_ymd(
|
||||
boost::string_view from,
|
||||
year_month_day& to
|
||||
)
|
||||
inline errc deserialize_text_ymd(boost::string_view from, year_month_day& to)
|
||||
{
|
||||
using namespace textc;
|
||||
|
||||
@@ -108,7 +97,7 @@ inline errc deserialize_text_ymd(
|
||||
return errc::protocol_value_error;
|
||||
|
||||
// Copy to a NULL-terminated buffer
|
||||
char buffer [date_sz + 1] {};
|
||||
char buffer[date_sz + 1]{};
|
||||
std::memcpy(buffer, from.data(), from.size());
|
||||
|
||||
// Parse individual components
|
||||
@@ -126,13 +115,10 @@ inline errc deserialize_text_ymd(
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
inline errc deserialize_text_value_date(
|
||||
boost::string_view from,
|
||||
field_view& to
|
||||
) noexcept
|
||||
inline errc deserialize_text_value_date(boost::string_view from, field_view& to) noexcept
|
||||
{
|
||||
// Deserialize ymd
|
||||
year_month_day ymd {};
|
||||
year_month_day ymd{};
|
||||
auto err = deserialize_text_ymd(from, ymd);
|
||||
if (err != errc::ok)
|
||||
return err;
|
||||
@@ -167,14 +153,14 @@ inline errc deserialize_text_value_datetime(
|
||||
return errc::protocol_value_error;
|
||||
|
||||
// Deserialize date part
|
||||
year_month_day ymd {};
|
||||
year_month_day ymd{};
|
||||
auto err = deserialize_text_ymd(from.substr(0, date_sz), ymd);
|
||||
if (err != errc::ok)
|
||||
return err;
|
||||
|
||||
// Copy to NULL-terminated buffer
|
||||
constexpr std::size_t datetime_time_first = date_sz + 1; // date + space
|
||||
char buffer [datetime_max_sz - datetime_time_first + 1] {};
|
||||
constexpr std::size_t datetime_time_first = date_sz + 1; // date + space
|
||||
char buffer[datetime_max_sz - datetime_time_first + 1]{};
|
||||
std::memcpy(buffer, from.data() + datetime_time_first, from.size() - datetime_time_first);
|
||||
|
||||
// Parse
|
||||
@@ -183,16 +169,15 @@ inline errc deserialize_text_value_datetime(
|
||||
char extra_char;
|
||||
if (decimals)
|
||||
{
|
||||
int parsed = sscanf(buffer, "%2u:%2u:%2u.%6u%c",
|
||||
&hours, &minutes, &seconds, µs, &extra_char);
|
||||
int parsed =
|
||||
sscanf(buffer, "%2u:%2u:%2u.%6u%c", &hours, &minutes, &seconds, µs, &extra_char);
|
||||
if (parsed != 4)
|
||||
return errc::protocol_value_error;
|
||||
micros = compute_micros(micros, decimals);
|
||||
}
|
||||
else
|
||||
{
|
||||
int parsed = sscanf(buffer, "%2u:%2u:%2u%c",
|
||||
&hours, &minutes, &seconds, &extra_char);
|
||||
int parsed = sscanf(buffer, "%2u:%2u:%2u%c", &hours, &minutes, &seconds, &extra_char);
|
||||
if (parsed != 3)
|
||||
return errc::protocol_value_error;
|
||||
}
|
||||
@@ -200,10 +185,7 @@ inline errc deserialize_text_value_datetime(
|
||||
// Validity check. We make this check before
|
||||
// the invalid date check to make invalid dates with incorrect
|
||||
// hours/mins/secs/micros fail
|
||||
if (hours > max_hour ||
|
||||
minutes > max_min ||
|
||||
seconds > max_sec ||
|
||||
micros > max_micro)
|
||||
if (hours > max_hour || minutes > max_min || seconds > max_sec || micros > max_micro)
|
||||
{
|
||||
return errc::protocol_value_error;
|
||||
}
|
||||
@@ -217,21 +199,15 @@ inline errc deserialize_text_value_datetime(
|
||||
}
|
||||
|
||||
// Sum it up. Doing time of day independently to prevent overflow
|
||||
date d (days(ymd_to_days(ymd)));
|
||||
auto time_of_day =
|
||||
std::chrono::hours(hours) +
|
||||
std::chrono::minutes(minutes) +
|
||||
std::chrono::seconds(seconds) +
|
||||
std::chrono::microseconds(micros);
|
||||
date d(days(ymd_to_days(ymd)));
|
||||
auto time_of_day = std::chrono::hours(hours) + std::chrono::minutes(minutes) +
|
||||
std::chrono::seconds(seconds) + std::chrono::microseconds(micros);
|
||||
to = field_view(d + time_of_day);
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
inline errc deserialize_text_value_time(
|
||||
boost::string_view from,
|
||||
field_view& to,
|
||||
const metadata& meta
|
||||
) noexcept
|
||||
inline errc
|
||||
deserialize_text_value_time(boost::string_view from, field_view& to, const metadata& meta) noexcept
|
||||
{
|
||||
using namespace textc;
|
||||
|
||||
@@ -240,13 +216,13 @@ inline errc deserialize_text_value_time(
|
||||
|
||||
// size check
|
||||
std::size_t actual_min_size = time_min_sz + (decimals ? decimals + 1 : 0);
|
||||
std::size_t actual_max_size = actual_min_size + 1 + 1; // hour extra character and sign
|
||||
std::size_t actual_max_size = actual_min_size + 1 + 1; // hour extra character and sign
|
||||
assert(actual_max_size <= time_max_sz);
|
||||
if (from.size() < actual_min_size || from.size() > actual_max_size)
|
||||
return errc::protocol_value_error;
|
||||
|
||||
// Copy to NULL-terminated buffer
|
||||
char buffer [time_max_sz + 1] {};
|
||||
char buffer[time_max_sz + 1]{};
|
||||
memcpy(buffer, from.data(), from.size());
|
||||
|
||||
// Sign
|
||||
@@ -259,7 +235,8 @@ inline errc deserialize_text_value_time(
|
||||
char extra_char;
|
||||
if (decimals)
|
||||
{
|
||||
int parsed = sscanf(first, "%3u:%2u:%2u.%6u%c", &hours, &minutes, &seconds, µs, &extra_char);
|
||||
int parsed =
|
||||
sscanf(first, "%3u:%2u:%2u.%6u%c", &hours, &minutes, &seconds, µs, &extra_char);
|
||||
if (parsed != 4)
|
||||
return errc::protocol_value_error;
|
||||
micros = compute_micros(micros, decimals);
|
||||
@@ -272,20 +249,14 @@ inline errc deserialize_text_value_time(
|
||||
}
|
||||
|
||||
// Range check
|
||||
if (hours > time_max_hour ||
|
||||
minutes > max_min ||
|
||||
seconds > max_sec ||
|
||||
micros > max_micro)
|
||||
if (hours > time_max_hour || minutes > max_min || seconds > max_sec || micros > max_micro)
|
||||
{
|
||||
return errc::protocol_value_error;
|
||||
}
|
||||
|
||||
// Sum it
|
||||
auto res =
|
||||
std::chrono::hours(hours) +
|
||||
std::chrono::minutes(minutes) +
|
||||
std::chrono::seconds(seconds) +
|
||||
std::chrono::microseconds(micros);
|
||||
auto res = std::chrono::hours(hours) + std::chrono::minutes(minutes) +
|
||||
std::chrono::seconds(seconds) + std::chrono::microseconds(micros);
|
||||
if (is_negative)
|
||||
{
|
||||
res = -res;
|
||||
@@ -296,9 +267,9 @@ inline errc deserialize_text_value_time(
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
inline boost::mysql::errc boost::mysql::detail::deserialize_text_field(
|
||||
boost::string_view from,
|
||||
@@ -314,21 +285,14 @@ inline boost::mysql::errc boost::mysql::detail::deserialize_text_field(
|
||||
case protocol_field_type::int24:
|
||||
case protocol_field_type::long_:
|
||||
case protocol_field_type::year:
|
||||
case protocol_field_type::longlong:
|
||||
return deserialize_text_value_int(from, output, meta);
|
||||
case protocol_field_type::bit:
|
||||
return deserialize_bit(from, output);
|
||||
case protocol_field_type::float_:
|
||||
return deserialize_text_value_float<float>(from, output);
|
||||
case protocol_field_type::double_:
|
||||
return deserialize_text_value_float<double>(from, output);
|
||||
case protocol_field_type::longlong: return deserialize_text_value_int(from, output, meta);
|
||||
case protocol_field_type::bit: return deserialize_bit(from, output);
|
||||
case protocol_field_type::float_: return deserialize_text_value_float<float>(from, output);
|
||||
case protocol_field_type::double_: return deserialize_text_value_float<double>(from, output);
|
||||
case protocol_field_type::timestamp:
|
||||
case protocol_field_type::datetime:
|
||||
return deserialize_text_value_datetime(from, output, meta);
|
||||
case protocol_field_type::date:
|
||||
return deserialize_text_value_date(from, output);
|
||||
case protocol_field_type::time:
|
||||
return deserialize_text_value_time(from, output, meta);
|
||||
case protocol_field_type::datetime: return deserialize_text_value_datetime(from, output, meta);
|
||||
case protocol_field_type::date: return deserialize_text_value_date(from, output);
|
||||
case protocol_field_type::time: return deserialize_text_value_time(from, output, meta);
|
||||
// True string types
|
||||
case protocol_field_type::varchar:
|
||||
case protocol_field_type::var_string:
|
||||
@@ -343,14 +307,12 @@ inline boost::mysql::errc boost::mysql::detail::deserialize_text_field(
|
||||
case protocol_field_type::decimal:
|
||||
case protocol_field_type::newdecimal:
|
||||
case protocol_field_type::geometry:
|
||||
default:
|
||||
return deserialize_text_value_string(from, output, buffer_first);
|
||||
default: return deserialize_text_value_string(from, output, buffer_first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning( pop )
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,21 +12,16 @@
|
||||
|
||||
#include <boost/mysql/detail/protocol/handshake_messages.hpp>
|
||||
|
||||
|
||||
inline boost::mysql::errc
|
||||
boost::mysql::detail::serialization_traits<
|
||||
inline boost::mysql::errc boost::mysql::detail::serialization_traits<
|
||||
boost::mysql::detail::handshake_packet,
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields
|
||||
>::deserialize_(
|
||||
deserialization_context& ctx,
|
||||
handshake_packet& output
|
||||
) noexcept
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields>::
|
||||
deserialize_(deserialization_context& ctx, handshake_packet& output) noexcept
|
||||
{
|
||||
constexpr std::uint8_t auth1_length = 8;
|
||||
string_fixed<auth1_length> auth_plugin_data_part_1;
|
||||
string_fixed<2> capability_flags_low;
|
||||
string_fixed<2> capability_flags_high;
|
||||
std::uint8_t filler; // should be 0
|
||||
std::uint8_t filler; // should be 0
|
||||
std::uint8_t auth_plugin_data_len = 0;
|
||||
string_fixed<10> reserved;
|
||||
|
||||
@@ -51,22 +46,18 @@ boost::mysql::detail::serialization_traits<
|
||||
boost::endian::little_to_native_inplace(output.capability_falgs);
|
||||
|
||||
// Check minimum server capabilities to deserialize this frame
|
||||
capabilities cap (output.capability_falgs);
|
||||
capabilities cap(output.capability_falgs);
|
||||
if (!cap.has(CLIENT_PLUGIN_AUTH))
|
||||
return errc::server_unsupported;
|
||||
|
||||
// Deserialize following fields
|
||||
err = deserialize(
|
||||
ctx,
|
||||
auth_plugin_data_len,
|
||||
reserved
|
||||
);
|
||||
err = deserialize(ctx, auth_plugin_data_len, reserved);
|
||||
if (err != errc::ok)
|
||||
return err;
|
||||
|
||||
// Auth plugin data, second part
|
||||
auto auth2_length = static_cast<std::uint8_t>(
|
||||
std::max(13, auth_plugin_data_len - auth1_length));
|
||||
auto auth2_length =
|
||||
static_cast<std::uint8_t>(std::max(13, auth_plugin_data_len - auth1_length));
|
||||
const void* auth2_data = ctx.first();
|
||||
if (!ctx.enough_size(auth2_length))
|
||||
return errc::incomplete_message;
|
||||
@@ -80,28 +71,28 @@ boost::mysql::detail::serialization_traits<
|
||||
// Compose auth_plugin_data
|
||||
output.auth_plugin_data.clear();
|
||||
output.auth_plugin_data.append(auth_plugin_data_part_1.data(), auth1_length);
|
||||
output.auth_plugin_data.append(auth2_data, auth2_length - 1); // discard an extra trailing NULL byte
|
||||
output.auth_plugin_data.append(
|
||||
auth2_data,
|
||||
auth2_length - 1
|
||||
); // discard an extra trailing NULL byte
|
||||
|
||||
return errc::ok;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
boost::mysql::detail::serialization_traits<
|
||||
std::size_t boost::mysql::detail::serialization_traits<
|
||||
boost::mysql::detail::handshake_response_packet,
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields
|
||||
>::get_size_(
|
||||
const serialization_context& ctx,
|
||||
const handshake_response_packet& value
|
||||
) noexcept
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields>::
|
||||
get_size_(const serialization_context& ctx, const handshake_response_packet& value) noexcept
|
||||
{
|
||||
std::size_t res = get_size(
|
||||
ctx,
|
||||
value.client_flag,
|
||||
value.max_packet_size,
|
||||
value.character_set,
|
||||
value.username,
|
||||
value.auth_response
|
||||
) + 23; // filler
|
||||
ctx,
|
||||
value.client_flag,
|
||||
value.max_packet_size,
|
||||
value.character_set,
|
||||
value.username,
|
||||
value.auth_response
|
||||
) +
|
||||
23; // filler
|
||||
if (ctx.get_capabilities().has(CLIENT_CONNECT_WITH_DB))
|
||||
{
|
||||
res += get_size(ctx, value.database);
|
||||
@@ -110,14 +101,10 @@ boost::mysql::detail::serialization_traits<
|
||||
return res;
|
||||
}
|
||||
|
||||
inline void
|
||||
boost::mysql::detail::serialization_traits<
|
||||
inline void boost::mysql::detail::serialization_traits<
|
||||
boost::mysql::detail::handshake_response_packet,
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields
|
||||
>::serialize_(
|
||||
serialization_context& ctx,
|
||||
const handshake_response_packet& value
|
||||
) noexcept
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields>::
|
||||
serialize_(serialization_context& ctx, const handshake_response_packet& value) noexcept
|
||||
{
|
||||
serialize(
|
||||
ctx,
|
||||
@@ -136,14 +123,10 @@ boost::mysql::detail::serialization_traits<
|
||||
serialize(ctx, value.client_plugin_name);
|
||||
}
|
||||
|
||||
inline boost::mysql::errc
|
||||
boost::mysql::detail::serialization_traits<
|
||||
inline boost::mysql::errc boost::mysql::detail::serialization_traits<
|
||||
boost::mysql::detail::auth_switch_request_packet,
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields
|
||||
>::deserialize_(
|
||||
deserialization_context& ctx,
|
||||
auth_switch_request_packet& output
|
||||
) noexcept
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields>::
|
||||
deserialize_(deserialization_context& ctx, auth_switch_request_packet& output) noexcept
|
||||
{
|
||||
auto err = deserialize(ctx, output.plugin_name, output.auth_plugin_data);
|
||||
auto& auth_data = output.auth_plugin_data.value;
|
||||
@@ -156,6 +139,4 @@ boost::mysql::detail::serialization_traits<
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_PROTOCOL_IMPL_HANDSHAKE_MESSAGES_IPP_ */
|
||||
|
||||
@@ -10,54 +10,43 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/detail/protocol/prepared_statement_messages.hpp>
|
||||
#include <boost/mysql/detail/protocol/null_bitmap_traits.hpp>
|
||||
#include <boost/mysql/detail/protocol/binary_serialization.hpp>
|
||||
#include <boost/mysql/detail/protocol/null_bitmap_traits.hpp>
|
||||
#include <boost/mysql/detail/protocol/prepared_statement_messages.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
// Maps from an actual value to a protocol_field_type. Only value's type is used
|
||||
inline protocol_field_type get_protocol_field_type(
|
||||
const field_view& input
|
||||
) noexcept
|
||||
inline protocol_field_type get_protocol_field_type(const field_view& input) noexcept
|
||||
{
|
||||
switch (input.kind())
|
||||
{
|
||||
case field_kind::null: return protocol_field_type::null;
|
||||
case field_kind::int64: return protocol_field_type::longlong;
|
||||
case field_kind::uint64: return protocol_field_type::longlong;
|
||||
case field_kind::string: return protocol_field_type::varchar;
|
||||
case field_kind::float_: return protocol_field_type::float_;
|
||||
case field_kind::double_: return protocol_field_type::double_;
|
||||
case field_kind::date: return protocol_field_type::date;
|
||||
case field_kind::datetime: return protocol_field_type::datetime;
|
||||
case field_kind::time: return protocol_field_type::time;
|
||||
case field_kind::null: return protocol_field_type::null;
|
||||
case field_kind::int64: return protocol_field_type::longlong;
|
||||
case field_kind::uint64: return protocol_field_type::longlong;
|
||||
case field_kind::string: return protocol_field_type::varchar;
|
||||
case field_kind::float_: return protocol_field_type::float_;
|
||||
case field_kind::double_: return protocol_field_type::double_;
|
||||
case field_kind::date: return protocol_field_type::date;
|
||||
case field_kind::datetime: return protocol_field_type::datetime;
|
||||
case field_kind::time: return protocol_field_type::time;
|
||||
}
|
||||
}
|
||||
|
||||
// Whether to include the unsigned flag in the statement execute message
|
||||
// for a given value or not. Only value's type is used
|
||||
inline bool is_unsigned(
|
||||
const field_view& input
|
||||
) noexcept
|
||||
{
|
||||
return input.is_uint64();
|
||||
}
|
||||
inline bool is_unsigned(const field_view& input) noexcept { return input.is_uint64(); }
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
inline boost::mysql::errc
|
||||
boost::mysql::detail::serialization_traits<
|
||||
inline boost::mysql::errc boost::mysql::detail::serialization_traits<
|
||||
boost::mysql::detail::com_stmt_prepare_ok_packet,
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields
|
||||
>::deserialize_(
|
||||
deserialization_context& ctx,
|
||||
com_stmt_prepare_ok_packet& output
|
||||
) noexcept
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields>::
|
||||
deserialize_(deserialization_context& ctx, com_stmt_prepare_ok_packet& output) noexcept
|
||||
{
|
||||
std::uint8_t reserved;
|
||||
return deserialize(
|
||||
@@ -71,17 +60,16 @@ boost::mysql::detail::serialization_traits<
|
||||
}
|
||||
|
||||
template <class FieldViewFwdIterator>
|
||||
inline std::size_t
|
||||
boost::mysql::detail::serialization_traits<
|
||||
inline std::size_t boost::mysql::detail::serialization_traits<
|
||||
boost::mysql::detail::com_stmt_execute_packet<FieldViewFwdIterator>,
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields
|
||||
>::get_size_(
|
||||
const serialization_context& ctx,
|
||||
const com_stmt_execute_packet<FieldViewFwdIterator>& value
|
||||
) noexcept
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields>::
|
||||
get_size_(
|
||||
const serialization_context& ctx,
|
||||
const com_stmt_execute_packet<FieldViewFwdIterator>& value
|
||||
) noexcept
|
||||
{
|
||||
std::size_t res = 1 + // command ID
|
||||
get_size(ctx, value.statement_id, value.flags, value.iteration_count);
|
||||
std::size_t res = 1 + // command ID
|
||||
get_size(ctx, value.statement_id, value.flags, value.iteration_count);
|
||||
auto num_params = std::distance(value.params_begin, value.params_end);
|
||||
assert(num_params >= 0 && num_params <= 255);
|
||||
res += null_bitmap_traits(stmt_execute_null_bitmap_offset, num_params).byte_count();
|
||||
@@ -95,32 +83,25 @@ boost::mysql::detail::serialization_traits<
|
||||
}
|
||||
|
||||
template <class FieldViewFwdIterator>
|
||||
inline void
|
||||
boost::mysql::detail::serialization_traits<
|
||||
inline void boost::mysql::detail::serialization_traits<
|
||||
boost::mysql::detail::com_stmt_execute_packet<FieldViewFwdIterator>,
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields
|
||||
>::serialize_(
|
||||
serialization_context& ctx,
|
||||
const com_stmt_execute_packet<FieldViewFwdIterator>& input
|
||||
) noexcept
|
||||
boost::mysql::detail::serialization_tag::struct_with_fields>::
|
||||
serialize_(
|
||||
serialization_context& ctx,
|
||||
const com_stmt_execute_packet<FieldViewFwdIterator>& input
|
||||
) noexcept
|
||||
{
|
||||
constexpr std::uint8_t command_id = com_stmt_execute_packet<FieldViewFwdIterator>::command_id;
|
||||
serialize(
|
||||
ctx,
|
||||
command_id,
|
||||
input.statement_id,
|
||||
input.flags,
|
||||
input.iteration_count
|
||||
);
|
||||
serialize(ctx, command_id, input.statement_id, input.flags, input.iteration_count);
|
||||
|
||||
// Number of parameters
|
||||
auto num_params = std::distance(input.params_begin, input.params_end);
|
||||
assert(num_params >= 0 && num_params <= 255);
|
||||
|
||||
// NULL bitmap (already size zero if num_params == 0)
|
||||
null_bitmap_traits traits (stmt_execute_null_bitmap_offset, num_params);
|
||||
null_bitmap_traits traits(stmt_execute_null_bitmap_offset, num_params);
|
||||
std::size_t i = 0;
|
||||
std::memset(ctx.first(), 0, traits.byte_count()); // Initialize to zeroes
|
||||
std::memset(ctx.first(), 0, traits.byte_count()); // Initialize to zeroes
|
||||
for (auto it = input.params_begin; it != input.params_end; ++it, ++i)
|
||||
{
|
||||
if (it->is_null())
|
||||
@@ -149,5 +130,4 @@ boost::mysql::detail::serialization_traits<
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_PROTOCOL_IMPL_PREPARED_STATEMENT_MESSAGES_HPP_ */
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_PROTOCOL_NULL_BITMAP_TRAITS_HPP
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_NULL_BITMAP_TRAITS_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -21,11 +21,18 @@ class null_bitmap_traits
|
||||
std::size_t offset_;
|
||||
std::size_t num_fields_;
|
||||
|
||||
constexpr std::size_t byte_pos(std::size_t field_pos) const noexcept { return (field_pos + offset_) / 8; }
|
||||
constexpr std::size_t bit_pos(std::size_t field_pos) const noexcept { return (field_pos + offset_) % 8; }
|
||||
constexpr std::size_t byte_pos(std::size_t field_pos) const noexcept
|
||||
{
|
||||
return (field_pos + offset_) / 8;
|
||||
}
|
||||
constexpr std::size_t bit_pos(std::size_t field_pos) const noexcept
|
||||
{
|
||||
return (field_pos + offset_) % 8;
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr null_bitmap_traits(std::size_t offset, std::size_t num_fields) noexcept:
|
||||
offset_(offset), num_fields_ {num_fields} {};
|
||||
constexpr null_bitmap_traits(std::size_t offset, std::size_t num_fields) noexcept
|
||||
: offset_(offset), num_fields_{num_fields} {};
|
||||
constexpr std::size_t offset() const noexcept { return offset_; }
|
||||
constexpr std::size_t num_fields() const noexcept { return num_fields_; }
|
||||
|
||||
@@ -45,8 +52,8 @@ public:
|
||||
constexpr std::size_t stmt_execute_null_bitmap_offset = 0;
|
||||
constexpr std::size_t binary_row_null_bitmap_offset = 2;
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif /* INCLUDE_NULL_BITMAP_HPP_ */
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_PROTOCOL_PREPARED_STATEMENT_MESSAGES_HPP
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_PREPARED_STATEMENT_MESSAGES_HPP
|
||||
|
||||
#include <boost/mysql/detail/protocol/serialization.hpp>
|
||||
#include <boost/mysql/detail/protocol/constants.hpp>
|
||||
#include <boost/mysql/detail/protocol/serialization.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
|
||||
namespace boost {
|
||||
@@ -26,9 +26,7 @@ struct com_stmt_prepare_packet
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
std::forward<Callable>(cb)(
|
||||
self.statement
|
||||
);
|
||||
std::forward<Callable>(cb)(self.statement);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -46,21 +44,25 @@ struct com_stmt_prepare_ok_packet
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
// clang-format off
|
||||
std::forward<Callable>(cb)(
|
||||
self.statement_id,
|
||||
self.num_columns,
|
||||
self.num_params,
|
||||
self.warning_count
|
||||
);
|
||||
// clang-format on
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct serialization_traits<com_stmt_prepare_ok_packet, serialization_tag::struct_with_fields> :
|
||||
noop_serialize<com_stmt_prepare_ok_packet>
|
||||
struct serialization_traits<com_stmt_prepare_ok_packet, serialization_tag::struct_with_fields>
|
||||
: noop_serialize<com_stmt_prepare_ok_packet>
|
||||
{
|
||||
static inline errc deserialize_(deserialization_context& ctx,
|
||||
com_stmt_prepare_ok_packet& output) noexcept;
|
||||
static inline errc deserialize_(
|
||||
deserialization_context& ctx,
|
||||
com_stmt_prepare_ok_packet& output
|
||||
) noexcept;
|
||||
};
|
||||
|
||||
// execute
|
||||
@@ -80,25 +82,31 @@ struct com_stmt_execute_packet
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
// clang-format off
|
||||
std::forward<Callable>(cb)(
|
||||
self.statement_id,
|
||||
self.flags,
|
||||
self.iteration_count,
|
||||
self.new_params_bind_flag
|
||||
);
|
||||
// clang-format on
|
||||
}
|
||||
};
|
||||
|
||||
template <class FieldViewFwdIterator>
|
||||
struct serialization_traits<
|
||||
com_stmt_execute_packet<FieldViewFwdIterator>,
|
||||
serialization_tag::struct_with_fields
|
||||
> : noop_deserialize<com_stmt_execute_packet<FieldViewFwdIterator>>
|
||||
serialization_tag::struct_with_fields>
|
||||
: noop_deserialize<com_stmt_execute_packet<FieldViewFwdIterator>>
|
||||
{
|
||||
static inline std::size_t get_size_(const serialization_context& ctx,
|
||||
const com_stmt_execute_packet<FieldViewFwdIterator>& value) noexcept;
|
||||
static inline void serialize_(serialization_context& ctx,
|
||||
const com_stmt_execute_packet<FieldViewFwdIterator>& input) noexcept;
|
||||
static inline std::size_t get_size_(
|
||||
const serialization_context& ctx,
|
||||
const com_stmt_execute_packet<FieldViewFwdIterator>& value
|
||||
) noexcept;
|
||||
static inline void serialize_(
|
||||
serialization_context& ctx,
|
||||
const com_stmt_execute_packet<FieldViewFwdIterator>& input
|
||||
) noexcept;
|
||||
};
|
||||
|
||||
struct com_stmt_execute_param_meta_packet
|
||||
@@ -109,10 +117,7 @@ struct com_stmt_execute_param_meta_packet
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
std::forward<Callable>(cb)(
|
||||
self.type,
|
||||
self.unsigned_flag
|
||||
);
|
||||
std::forward<Callable>(cb)(self.type, self.unsigned_flag);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -126,16 +131,13 @@ struct com_stmt_close_packet
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
std::forward<Callable>(cb)(
|
||||
self.statement_id
|
||||
);
|
||||
std::forward<Callable>(cb)(self.statement_id);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/protocol/impl/prepared_statement_messages.hpp>
|
||||
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_PROTOCOL_TYPES_HPP
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -24,10 +25,14 @@ struct value_holder
|
||||
{
|
||||
using value_type = T;
|
||||
|
||||
static_assert(std::is_nothrow_default_constructible<T>::value,
|
||||
"value_holder<T> should be nothrow default constructible");
|
||||
static_assert(std::is_nothrow_move_constructible<T>::value,
|
||||
"value_holder<T> should be nothrow move constructible");
|
||||
static_assert(
|
||||
std::is_nothrow_default_constructible<T>::value,
|
||||
"value_holder<T> should be nothrow default constructible"
|
||||
);
|
||||
static_assert(
|
||||
std::is_nothrow_move_constructible<T>::value,
|
||||
"value_holder<T> should be nothrow move constructible"
|
||||
);
|
||||
|
||||
value_type value;
|
||||
|
||||
@@ -39,19 +44,36 @@ struct value_holder
|
||||
constexpr bool operator!=(const value_holder<T>& rhs) const { return value != rhs.value; }
|
||||
};
|
||||
|
||||
struct int3 : value_holder<std::uint32_t> { using value_holder::value_holder; };
|
||||
struct int_lenenc : value_holder<std::uint64_t> { using value_holder::value_holder; };
|
||||
struct int3 : value_holder<std::uint32_t>
|
||||
{
|
||||
using value_holder::value_holder;
|
||||
};
|
||||
|
||||
struct string_null : value_holder<boost::string_view> { using value_holder::value_holder; };
|
||||
struct string_eof : value_holder<boost::string_view> { using value_holder::value_holder; };
|
||||
struct string_lenenc : value_holder<boost::string_view> { using value_holder::value_holder; };
|
||||
struct int_lenenc : value_holder<std::uint64_t>
|
||||
{
|
||||
using value_holder::value_holder;
|
||||
};
|
||||
|
||||
struct string_null : value_holder<boost::string_view>
|
||||
{
|
||||
using value_holder::value_holder;
|
||||
};
|
||||
|
||||
struct string_eof : value_holder<boost::string_view>
|
||||
{
|
||||
using value_holder::value_holder;
|
||||
};
|
||||
|
||||
struct string_lenenc : value_holder<boost::string_view>
|
||||
{
|
||||
using value_holder::value_holder;
|
||||
};
|
||||
|
||||
template <std::size_t size>
|
||||
using string_fixed = std::array<char, size>;
|
||||
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_QUERY_MESSAGES_HPP
|
||||
|
||||
#include <boost/mysql/detail/protocol/serialization.hpp>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace boost {
|
||||
@@ -24,14 +25,12 @@ struct com_query_packet
|
||||
template <class Self, class Callable>
|
||||
static void apply(Self& self, Callable&& cb)
|
||||
{
|
||||
std::forward<Callable>(cb)(
|
||||
self.query
|
||||
);
|
||||
std::forward<Callable>(cb)(self.query);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_PROTOCOL_QUERY_MESSAGES_HPP_ */
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_PROTOCOL_RESULTSET_ENCODING_HPP
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_RESULTSET_ENCODING_HPP
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
@@ -19,9 +18,8 @@ enum class resultset_encoding
|
||||
binary
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_COMMON_HPP_ */
|
||||
|
||||
@@ -8,15 +8,17 @@
|
||||
#ifndef BOOST_MYSQL_DETAIL_PROTOCOL_SERIALIZATION_HPP
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_SERIALIZATION_HPP
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
#include <boost/mysql/detail/protocol/deserialization_context.hpp>
|
||||
#include <boost/mysql/detail/protocol/protocol_types.hpp>
|
||||
#include <boost/mysql/detail/protocol/serialization_context.hpp>
|
||||
#include <boost/mysql/detail/protocol/deserialization_context.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
@@ -32,7 +34,7 @@ enum class serialization_tag
|
||||
template <class T>
|
||||
constexpr serialization_tag get_serialization_tag();
|
||||
|
||||
template <class T, serialization_tag=get_serialization_tag<T>()>
|
||||
template <class T, serialization_tag = get_serialization_tag<T>()>
|
||||
struct serialization_traits;
|
||||
|
||||
template <class... Types>
|
||||
@@ -50,7 +52,10 @@ struct serialization_traits<T, serialization_tag::plain_int>
|
||||
{
|
||||
static errc deserialize_(deserialization_context& ctx, T& output) noexcept;
|
||||
static void serialize_(serialization_context& ctx, T input) noexcept;
|
||||
static constexpr std::size_t get_size_(const serialization_context&, T) noexcept { return sizeof(T); }
|
||||
static constexpr std::size_t get_size_(const serialization_context&, T) noexcept
|
||||
{
|
||||
return sizeof(T);
|
||||
}
|
||||
};
|
||||
|
||||
// int3
|
||||
@@ -82,7 +87,6 @@ struct serialization_traits<int_lenenc, serialization_tag::none>
|
||||
static inline std::size_t get_size_(const serialization_context&, int_lenenc input) noexcept;
|
||||
};
|
||||
|
||||
|
||||
// string_fixed
|
||||
template <std::size_t N>
|
||||
struct serialization_traits<string_fixed<N>, serialization_tag::none>
|
||||
@@ -99,13 +103,13 @@ struct serialization_traits<string_fixed<N>, serialization_tag::none>
|
||||
{
|
||||
ctx.write(input.data(), N);
|
||||
}
|
||||
static constexpr std::size_t get_size_(const serialization_context&, const string_fixed<N>&) noexcept
|
||||
static constexpr std::size_t
|
||||
get_size_(const serialization_context&, const string_fixed<N>&) noexcept
|
||||
{
|
||||
return N;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// string_null
|
||||
template <>
|
||||
struct serialization_traits<string_null, serialization_tag::none>
|
||||
@@ -114,7 +118,7 @@ struct serialization_traits<string_null, serialization_tag::none>
|
||||
static inline void serialize_(serialization_context& ctx, string_null input) noexcept
|
||||
{
|
||||
ctx.write(input.value.data(), input.value.size());
|
||||
ctx.write(0); // null terminator
|
||||
ctx.write(0); // null terminator
|
||||
}
|
||||
static inline std::size_t get_size_(const serialization_context&, string_null input) noexcept
|
||||
{
|
||||
@@ -147,7 +151,8 @@ struct serialization_traits<string_lenenc, serialization_tag::none>
|
||||
serialize(ctx, int_lenenc(input.value.size()));
|
||||
ctx.write(input.value.data(), input.value.size());
|
||||
}
|
||||
static inline std::size_t get_size_(const serialization_context& ctx, string_lenenc input) noexcept
|
||||
static inline std::size_t
|
||||
get_size_(const serialization_context& ctx, string_lenenc input) noexcept
|
||||
{
|
||||
return get_size(ctx, int_lenenc(input.value.size())) + input.value.size();
|
||||
}
|
||||
@@ -170,7 +175,10 @@ struct serialization_traits<T, serialization_tag::enumeration>
|
||||
{
|
||||
serialize(ctx, static_cast<underlying_type>(input));
|
||||
}
|
||||
static std::size_t get_size_(const serialization_context&, T) noexcept { return sizeof(underlying_type); }
|
||||
static std::size_t get_size_(const serialization_context&, T) noexcept
|
||||
{
|
||||
return sizeof(underlying_type);
|
||||
}
|
||||
};
|
||||
|
||||
// Structs and commands
|
||||
@@ -199,7 +207,10 @@ struct serialization_traits<T, serialization_tag::struct_with_fields>
|
||||
template <class T>
|
||||
struct noop_serialize
|
||||
{
|
||||
static inline std::size_t get_size_(const serialization_context&, const T&) noexcept { return 0; }
|
||||
static inline std::size_t get_size_(const serialization_context&, const T&) noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void serialize_(serialization_context&, const T&) noexcept {}
|
||||
};
|
||||
|
||||
@@ -218,20 +229,18 @@ void serialize_message(
|
||||
);
|
||||
|
||||
template <class Deserializable>
|
||||
error_code deserialize_message(
|
||||
deserialization_context& ctx,
|
||||
Deserializable& output
|
||||
);
|
||||
error_code deserialize_message(deserialization_context& ctx, Deserializable& output);
|
||||
|
||||
// Helpers for (de) serializing a set of fields
|
||||
template <class... Types>
|
||||
void serialize_fields(serialization_context& ctx, const Types&... fields) noexcept;
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/detail/protocol/impl/serialization.hpp>
|
||||
|
||||
#include <boost/mysql/detail/protocol/impl/serialization.ipp>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
#define BOOST_MYSQL_DETAIL_PROTOCOL_SERIALIZATION_CONTEXT_HPP
|
||||
|
||||
#include <boost/mysql/detail/protocol/capabilities.hpp>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
@@ -21,22 +23,32 @@ class serialization_context
|
||||
{
|
||||
std::uint8_t* first_;
|
||||
capabilities capabilities_;
|
||||
|
||||
public:
|
||||
serialization_context(capabilities caps, std::uint8_t* first = nullptr) noexcept:
|
||||
first_(first), capabilities_(caps) {};
|
||||
serialization_context(capabilities caps, std::uint8_t* first = nullptr) noexcept
|
||||
: first_(first), capabilities_(caps){};
|
||||
std::uint8_t* first() const noexcept { return first_; }
|
||||
void set_first(std::uint8_t* new_first) noexcept { first_ = new_first; }
|
||||
void set_first(boost::asio::mutable_buffer buff) noexcept { first_ = static_cast<std::uint8_t*>(buff.data()); }
|
||||
void set_first(boost::asio::mutable_buffer buff) noexcept
|
||||
{
|
||||
first_ = static_cast<std::uint8_t*>(buff.data());
|
||||
}
|
||||
void advance(std::size_t size) noexcept { first_ += size; }
|
||||
capabilities get_capabilities() const noexcept { return capabilities_; }
|
||||
void write(const void* buffer, std::size_t size) noexcept { memcpy(first_, buffer, size); advance(size); }
|
||||
void write(std::uint8_t elm) noexcept { *first_ = elm; ++first_; }
|
||||
void write(const void* buffer, std::size_t size) noexcept
|
||||
{
|
||||
memcpy(first_, buffer, size);
|
||||
advance(size);
|
||||
}
|
||||
void write(std::uint8_t elm) noexcept
|
||||
{
|
||||
*first_ = elm;
|
||||
++first_;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_DETAIL_PROTOCOL_SERIALIZATION_CONTEXT_HPP_ */
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
#ifndef BOOST_MYSQL_ERROR_HPP
|
||||
#define BOOST_MYSQL_ERROR_HPP
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <boost/mysql/errc.hpp>
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
|
||||
@@ -31,12 +33,13 @@ inline error_code make_error_code(errc error);
|
||||
class error_info
|
||||
{
|
||||
std::string msg_;
|
||||
|
||||
public:
|
||||
/// Default constructor.
|
||||
error_info() = default;
|
||||
|
||||
/// Initialization constructor.
|
||||
error_info(std::string&& err) noexcept: msg_(std::move(err)) {}
|
||||
error_info(std::string&& err) noexcept : msg_(std::move(err)) {}
|
||||
|
||||
/// Gets the error message.
|
||||
const std::string& message() const noexcept { return msg_; }
|
||||
@@ -52,13 +55,19 @@ public:
|
||||
* \relates error_info
|
||||
* \brief Compare two error_info objects.
|
||||
*/
|
||||
inline bool operator==(const error_info& lhs, const error_info& rhs) noexcept { return lhs.message() == rhs.message(); }
|
||||
inline bool operator==(const error_info& lhs, const error_info& rhs) noexcept
|
||||
{
|
||||
return lhs.message() == rhs.message();
|
||||
}
|
||||
|
||||
/**
|
||||
* \relates error_info
|
||||
* \brief Compare two error_info objects.
|
||||
*/
|
||||
inline bool operator!=(const error_info& lhs, const error_info& rhs) noexcept { return !(lhs==rhs); }
|
||||
inline bool operator!=(const error_info& lhs, const error_info& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* \relates error_info
|
||||
@@ -66,8 +75,8 @@ inline bool operator!=(const error_info& lhs, const error_info& rhs) noexcept {
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& os, const error_info& v) { return os << v.message(); }
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/impl/error.hpp>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define BOOST_MYSQL_EXECUTE_PARAMS_HPP
|
||||
|
||||
#include <boost/mysql/detail/auxiliar/field_type_traits.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -16,63 +17,61 @@ namespace boost {
|
||||
namespace mysql {
|
||||
|
||||
/**
|
||||
* \brief Represents the parameters required to execute a [reflink statement_base].
|
||||
* \details In essence, this class contains an iterator range \\[first, last), pointing
|
||||
* to a sequence of [reflink value]s that will be used as parameters to execute a
|
||||
* [reflink statement_base]. FieldViewFwdIterator must meet the [reflink FieldViewFwdIterator]
|
||||
* type requirements.
|
||||
*
|
||||
* In the future, this class may define extra members providing finer control
|
||||
* over prepared statement execution.
|
||||
*
|
||||
* The \ref make_execute_params helper functions make it easier to create
|
||||
* instances of this class.
|
||||
*/
|
||||
* \brief Represents the parameters required to execute a [reflink statement_base].
|
||||
* \details In essence, this class contains an iterator range \\[first, last), pointing
|
||||
* to a sequence of [reflink value]s that will be used as parameters to execute a
|
||||
* [reflink statement_base]. FieldViewFwdIterator must meet the [reflink FieldViewFwdIterator]
|
||||
* type requirements.
|
||||
*
|
||||
* In the future, this class may define extra members providing finer control
|
||||
* over prepared statement execution.
|
||||
*
|
||||
* The \ref make_execute_params helper functions make it easier to create
|
||||
* instances of this class.
|
||||
*/
|
||||
template <class FieldViewFwdIterator>
|
||||
class execute_params
|
||||
{
|
||||
FieldViewFwdIterator first_;
|
||||
FieldViewFwdIterator last_;
|
||||
static_assert(detail::is_field_view_forward_iterator<FieldViewFwdIterator>::value,
|
||||
"FieldViewFwdIterator requirements not met");
|
||||
static_assert(
|
||||
detail::is_field_view_forward_iterator<FieldViewFwdIterator>::value,
|
||||
"FieldViewFwdIterator requirements not met"
|
||||
);
|
||||
|
||||
public:
|
||||
/// Constructor.
|
||||
constexpr execute_params(FieldViewFwdIterator first, FieldViewFwdIterator last) :
|
||||
first_(first), last_(last) {}
|
||||
constexpr execute_params(FieldViewFwdIterator first, FieldViewFwdIterator last)
|
||||
: first_(first), last_(last)
|
||||
{
|
||||
}
|
||||
|
||||
/// Retrieves the parameter value range's begin.
|
||||
/// Retrieves the parameter value range's begin.
|
||||
constexpr FieldViewFwdIterator first() const { return first_; }
|
||||
|
||||
/// Retrieves the parameter value range's end.
|
||||
/// Retrieves the parameter value range's end.
|
||||
constexpr FieldViewFwdIterator last() const { return last_; }
|
||||
};
|
||||
|
||||
template <
|
||||
class FieldViewFwdIterator,
|
||||
class EnableIf = detail::enable_if_field_view_forward_iterator<FieldViewFwdIterator>
|
||||
>
|
||||
class EnableIf = detail::enable_if_field_view_forward_iterator<FieldViewFwdIterator> >
|
||||
constexpr execute_params<FieldViewFwdIterator>
|
||||
make_execute_params(
|
||||
FieldViewFwdIterator first,
|
||||
FieldViewFwdIterator last
|
||||
)
|
||||
make_execute_params(FieldViewFwdIterator first, FieldViewFwdIterator last)
|
||||
{
|
||||
return execute_params<FieldViewFwdIterator>(first, last);
|
||||
}
|
||||
|
||||
template <
|
||||
class FieldViewCollection,
|
||||
class EnableIf = detail::enable_if_field_view_collection<FieldViewCollection>
|
||||
>
|
||||
constexpr auto make_execute_params(
|
||||
const FieldViewCollection& col
|
||||
) -> execute_params<decltype(std::begin(col))>
|
||||
class EnableIf = detail::enable_if_field_view_collection<FieldViewCollection> >
|
||||
constexpr auto make_execute_params(const FieldViewCollection& col)
|
||||
-> execute_params<decltype(std::begin(col))>
|
||||
{
|
||||
return make_execute_params(std::begin(col), std::end(col));
|
||||
}
|
||||
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
#ifndef BOOST_MYSQL_FIELD_HPP
|
||||
#define BOOST_MYSQL_FIELD_HPP
|
||||
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/datetime_types.hpp>
|
||||
#include <boost/mysql/field_kind.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/field_impl.hpp>
|
||||
#include <boost/mysql/field_kind.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/variant2/variant.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
@@ -49,10 +51,14 @@ public:
|
||||
explicit field(const std::string& v) : repr_(v) {}
|
||||
explicit field(std::string&& v) noexcept : repr_(std::move(v)) {}
|
||||
explicit field(const char* v) : repr_(boost::variant2::in_place_type_t<std::string>(), v) {}
|
||||
explicit field(boost::string_view v) : repr_(boost::variant2::in_place_type_t<std::string>(), v) {}
|
||||
#ifdef __cpp_lib_string_view
|
||||
explicit field(std::string_view v) : repr_(boost::variant2::in_place_type_t<std::string>(), v) {}
|
||||
#endif
|
||||
explicit field(boost::string_view v) : repr_(boost::variant2::in_place_type_t<std::string>(), v)
|
||||
{
|
||||
}
|
||||
#ifdef __cpp_lib_string_view
|
||||
explicit field(std::string_view v) : repr_(boost::variant2::in_place_type_t<std::string>(), v)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
explicit field(float v) noexcept : repr_(v) {}
|
||||
explicit field(double v) noexcept : repr_(v) {}
|
||||
explicit field(const date& v) noexcept : repr_(v) {}
|
||||
@@ -60,30 +66,118 @@ public:
|
||||
explicit field(const time& v) noexcept : repr_(v) {}
|
||||
field(const field_view& v) { from_view(v); }
|
||||
|
||||
field& operator=(std::nullptr_t) noexcept { emplace_null(); return *this; }
|
||||
field& operator=(signed char v) noexcept { emplace_int64(v); return *this; }
|
||||
field& operator=(short v) noexcept { emplace_int64(v); return *this; }
|
||||
field& operator=(int v) noexcept { emplace_int64(v); return *this; }
|
||||
field& operator=(long v) noexcept { emplace_int64(v); return *this; }
|
||||
field& operator=(long long v) noexcept { emplace_int64(v); return *this; }
|
||||
field& operator=(unsigned char v) noexcept { emplace_uint64(v); return *this; }
|
||||
field& operator=(unsigned short v) noexcept { emplace_uint64(v); return *this; }
|
||||
field& operator=(unsigned int v) noexcept { emplace_uint64(v); return *this; }
|
||||
field& operator=(unsigned long v) noexcept { emplace_uint64(v); return *this; }
|
||||
field& operator=(unsigned long long v) noexcept { emplace_uint64(v); return *this; }
|
||||
field& operator=(const std::string& v) { emplace_string(v); return *this; }
|
||||
field& operator=(std::string&& v) { emplace_string(std::move(v)); return *this; }
|
||||
field& operator=(const char* v) { emplace_string(v); return *this; }
|
||||
field& operator=(boost::string_view v) { emplace_string(v); return *this; }
|
||||
#ifdef __cpp_lib_string_view
|
||||
field& operator=(std::string_view v) { emplace_string(v); return *this; }
|
||||
#endif
|
||||
field& operator=(float v) noexcept { emplace_float(v); return *this; }
|
||||
field& operator=(double v) noexcept { emplace_double(v); return *this; }
|
||||
field& operator=(const date& v) noexcept { emplace_date(v); return *this; }
|
||||
field& operator=(const datetime& v) noexcept { emplace_datetime(v); return *this; }
|
||||
field& operator=(const time& v) noexcept { emplace_time(v); return *this; }
|
||||
field& operator=(const field_view& v) { from_view(v); return *this; }
|
||||
field& operator=(std::nullptr_t) noexcept
|
||||
{
|
||||
emplace_null();
|
||||
return *this;
|
||||
}
|
||||
field& operator=(signed char v) noexcept
|
||||
{
|
||||
emplace_int64(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(short v) noexcept
|
||||
{
|
||||
emplace_int64(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(int v) noexcept
|
||||
{
|
||||
emplace_int64(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(long v) noexcept
|
||||
{
|
||||
emplace_int64(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(long long v) noexcept
|
||||
{
|
||||
emplace_int64(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(unsigned char v) noexcept
|
||||
{
|
||||
emplace_uint64(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(unsigned short v) noexcept
|
||||
{
|
||||
emplace_uint64(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(unsigned int v) noexcept
|
||||
{
|
||||
emplace_uint64(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(unsigned long v) noexcept
|
||||
{
|
||||
emplace_uint64(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(unsigned long long v) noexcept
|
||||
{
|
||||
emplace_uint64(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(const std::string& v)
|
||||
{
|
||||
emplace_string(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(std::string&& v)
|
||||
{
|
||||
emplace_string(std::move(v));
|
||||
return *this;
|
||||
}
|
||||
field& operator=(const char* v)
|
||||
{
|
||||
emplace_string(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(boost::string_view v)
|
||||
{
|
||||
emplace_string(v);
|
||||
return *this;
|
||||
}
|
||||
#ifdef __cpp_lib_string_view
|
||||
field& operator=(std::string_view v)
|
||||
{
|
||||
emplace_string(v);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
field& operator=(float v) noexcept
|
||||
{
|
||||
emplace_float(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(double v) noexcept
|
||||
{
|
||||
emplace_double(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(const date& v) noexcept
|
||||
{
|
||||
emplace_date(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(const datetime& v) noexcept
|
||||
{
|
||||
emplace_datetime(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(const time& v) noexcept
|
||||
{
|
||||
emplace_time(v);
|
||||
return *this;
|
||||
}
|
||||
field& operator=(const field_view& v)
|
||||
{
|
||||
from_view(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
field_kind kind() const noexcept { return repr_.kind(); }
|
||||
|
||||
@@ -140,9 +234,9 @@ public:
|
||||
void emplace_string(std::string&& v) noexcept { repr_.data.emplace<std::string>(std::move(v)); }
|
||||
void emplace_string(const char* v) noexcept { repr_.data.emplace<std::string>(v); }
|
||||
void emplace_string(boost::string_view v) noexcept { repr_.data.emplace<std::string>(v); }
|
||||
#ifdef __cpp_lib_string_view
|
||||
#ifdef __cpp_lib_string_view
|
||||
void emplace_string(std::string_view v) noexcept { repr_.data.emplace<std::string>(v); }
|
||||
#endif
|
||||
#endif
|
||||
void emplace_float(float v) noexcept { repr_.data.emplace<float>(v); }
|
||||
void emplace_double(double v) noexcept { repr_.data.emplace<double>(v); }
|
||||
void emplace_date(const date& v) noexcept { repr_.data.emplace<date>(v); }
|
||||
@@ -150,27 +244,36 @@ public:
|
||||
void emplace_time(const time& v) noexcept { repr_.data.emplace<time>(v); }
|
||||
|
||||
inline operator field_view() const noexcept { return field_view(&repr_); }
|
||||
|
||||
private:
|
||||
detail::field_impl repr_;
|
||||
|
||||
inline void from_view(const field_view& v);
|
||||
};
|
||||
|
||||
inline bool operator==(const field& lhs, const field& rhs) noexcept { return field_view(lhs) == field_view(rhs); }
|
||||
inline bool operator==(const field& lhs, const field& rhs) noexcept
|
||||
{
|
||||
return field_view(lhs) == field_view(rhs);
|
||||
}
|
||||
inline bool operator!=(const field& lhs, const field& rhs) noexcept { return !(lhs == rhs); }
|
||||
|
||||
inline bool operator==(const field_view& lhs, const field& rhs) noexcept { return lhs == field_view(rhs); }
|
||||
inline bool operator==(const field_view& lhs, const field& rhs) noexcept
|
||||
{
|
||||
return lhs == field_view(rhs);
|
||||
}
|
||||
inline bool operator!=(const field_view& lhs, const field& rhs) noexcept { return !(lhs == rhs); }
|
||||
|
||||
inline bool operator==(const field& lhs, const field_view& rhs) noexcept { return field_view(lhs) == rhs; }
|
||||
inline bool operator==(const field& lhs, const field_view& rhs) noexcept
|
||||
{
|
||||
return field_view(lhs) == rhs;
|
||||
}
|
||||
inline bool operator!=(const field& lhs, const field_view& rhs) noexcept { return !(lhs == rhs); }
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const field& v);
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/impl/field.hpp>
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,8 +29,8 @@ enum class field_kind
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, field_kind v);
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/impl/field_kind.ipp>
|
||||
|
||||
|
||||
@@ -23,31 +23,31 @@ namespace mysql {
|
||||
*/
|
||||
enum class field_type
|
||||
{
|
||||
tinyint, ///< `__TINYINT__` (signed and unsigned).
|
||||
smallint, ///< `__SMALLINT__` (signed and unsigned).
|
||||
mediumint, ///< `__MEDIUMINT__` (signed and unsigned).
|
||||
int_, ///< `__INT__` (signed and unsigned).
|
||||
bigint, ///< `__BIGINT__` (signed and unsigned).
|
||||
float_, ///< `__FLOAT__` (warning: FLOAT(p) where p >= 24 creates a DOUBLE column).
|
||||
double_, ///< `__DOUBLE__`
|
||||
decimal, ///< `__DECIMAL__`
|
||||
bit, ///< `__BIT__`
|
||||
year, ///< `__YEAR__`
|
||||
time, ///< `__TIME__`
|
||||
date, ///< `__DATE__`
|
||||
datetime, ///< `__DATETIME__`
|
||||
timestamp, ///< `__TIMESTAMP__`
|
||||
char_, ///< `__CHAR__` (any length)
|
||||
varchar, ///< `__VARCHAR__` (any length)
|
||||
binary, ///< `__BINARY__` (any length)
|
||||
varbinary, ///< `__VARBINARY__` (any length)
|
||||
text, ///< `__TEXT__` types (`TINYTEXT`, `MEDIUMTEXT`, `TEXT` and `LONGTEXT`)
|
||||
blob, ///< `__BLOB__` types (`TINYBLOB`, `MEDIUMBLOB`, `BLOB` and `LONGBLOB`)
|
||||
enum_, ///< `__ENUM__`
|
||||
set, ///< `__SET__`
|
||||
geometry, ///< `__GEOMETRY__`
|
||||
tinyint, ///< `__TINYINT__` (signed and unsigned).
|
||||
smallint, ///< `__SMALLINT__` (signed and unsigned).
|
||||
mediumint, ///< `__MEDIUMINT__` (signed and unsigned).
|
||||
int_, ///< `__INT__` (signed and unsigned).
|
||||
bigint, ///< `__BIGINT__` (signed and unsigned).
|
||||
float_, ///< `__FLOAT__` (warning: FLOAT(p) where p >= 24 creates a DOUBLE column).
|
||||
double_, ///< `__DOUBLE__`
|
||||
decimal, ///< `__DECIMAL__`
|
||||
bit, ///< `__BIT__`
|
||||
year, ///< `__YEAR__`
|
||||
time, ///< `__TIME__`
|
||||
date, ///< `__DATE__`
|
||||
datetime, ///< `__DATETIME__`
|
||||
timestamp, ///< `__TIMESTAMP__`
|
||||
char_, ///< `__CHAR__` (any length)
|
||||
varchar, ///< `__VARCHAR__` (any length)
|
||||
binary, ///< `__BINARY__` (any length)
|
||||
varbinary, ///< `__VARBINARY__` (any length)
|
||||
text, ///< `__TEXT__` types (`TINYTEXT`, `MEDIUMTEXT`, `TEXT` and `LONGTEXT`)
|
||||
blob, ///< `__BLOB__` types (`TINYBLOB`, `MEDIUMBLOB`, `BLOB` and `LONGBLOB`)
|
||||
enum_, ///< `__ENUM__`
|
||||
set, ///< `__SET__`
|
||||
geometry, ///< `__GEOMETRY__`
|
||||
|
||||
unknown, ///< None of the known types; maybe a new MySQL type we have no knowledge of.
|
||||
unknown, ///< None of the known types; maybe a new MySQL type we have no knowledge of.
|
||||
#ifndef BOOST_MYSQL_DOXYGEN
|
||||
_not_computed,
|
||||
#endif
|
||||
@@ -88,9 +88,7 @@ inline std::ostream& operator<<(std::ostream& os, field_type t)
|
||||
}
|
||||
}
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,16 +8,18 @@
|
||||
#ifndef BOOST_MYSQL_FIELD_VIEW_HPP
|
||||
#define BOOST_MYSQL_FIELD_VIEW_HPP
|
||||
|
||||
#include <boost/config/detail/suffix.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/string_view_offset.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/field_impl.hpp>
|
||||
#include <boost/mysql/datetime_types.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/field_impl.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/string_view_offset.hpp>
|
||||
#include <boost/mysql/field_kind.hpp>
|
||||
|
||||
#include <boost/config/detail/suffix.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <array>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -45,11 +47,11 @@ public:
|
||||
BOOST_CXX14_CONSTEXPR field_view() = default;
|
||||
|
||||
/**
|
||||
* \brief Constructs a NULL value.
|
||||
* \details
|
||||
* Caution: `value(NULL)` will __NOT__ match this overload. It will try to construct
|
||||
* a `boost::string_view` from a NULL C string, causing undefined behavior.
|
||||
*/
|
||||
* \brief Constructs a NULL value.
|
||||
* \details
|
||||
* Caution: `value(NULL)` will __NOT__ match this overload. It will try to construct
|
||||
* a `boost::string_view` from a NULL C string, causing undefined behavior.
|
||||
*/
|
||||
BOOST_CXX14_CONSTEXPR explicit field_view(std::nullptr_t) noexcept {}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR explicit inline field_view(signed char v) noexcept;
|
||||
@@ -72,16 +74,17 @@ public:
|
||||
BOOST_CXX14_CONSTEXPR explicit inline field_view(const time& v) noexcept;
|
||||
|
||||
// TODO: hide this
|
||||
BOOST_CXX14_CONSTEXPR explicit field_view(detail::string_view_offset v) noexcept : ikind_(internal_kind::sv_offset)
|
||||
BOOST_CXX14_CONSTEXPR explicit field_view(detail::string_view_offset v) noexcept
|
||||
: ikind_(internal_kind::sv_offset)
|
||||
{
|
||||
repr_.sv_offset = { v.offset(), v.size() };
|
||||
repr_.sv_offset = {v.offset(), v.size()};
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR explicit field_view(const detail::field_impl* v) noexcept : ikind_(internal_kind::field_ptr)
|
||||
BOOST_CXX14_CONSTEXPR explicit field_view(const detail::field_impl* v) noexcept
|
||||
: ikind_(internal_kind::field_ptr)
|
||||
{
|
||||
repr_.field_ptr = v;
|
||||
}
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline field_kind kind() const noexcept;
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool is_null() const noexcept { return kind() == field_kind::null; }
|
||||
@@ -91,7 +94,10 @@ public:
|
||||
BOOST_CXX14_CONSTEXPR bool is_float() const noexcept { return kind() == field_kind::float_; }
|
||||
BOOST_CXX14_CONSTEXPR bool is_double() const noexcept { return kind() == field_kind::double_; }
|
||||
BOOST_CXX14_CONSTEXPR bool is_date() const noexcept { return kind() == field_kind::date; }
|
||||
BOOST_CXX14_CONSTEXPR bool is_datetime() const noexcept { return kind() == field_kind::datetime; }
|
||||
BOOST_CXX14_CONSTEXPR bool is_datetime() const noexcept
|
||||
{
|
||||
return kind() == field_kind::datetime;
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR bool is_time() const noexcept { return kind() == field_kind::time; }
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline std::int64_t as_int64() const;
|
||||
@@ -112,11 +118,16 @@ public:
|
||||
BOOST_CXX14_CONSTEXPR inline datetime get_datetime() const noexcept;
|
||||
BOOST_CXX14_CONSTEXPR inline time get_time() const noexcept;
|
||||
|
||||
/// Tests for equality (type and value); see [link mysql.values.relational this section] for more info.
|
||||
/// Tests for equality (type and value); see [link mysql.values.relational this section] for
|
||||
/// more info.
|
||||
BOOST_CXX14_CONSTEXPR bool operator==(const field_view& rhs) const noexcept;
|
||||
|
||||
/// Tests for inequality (type and value); see [link mysql.values.relational this section] for more info.
|
||||
BOOST_CXX14_CONSTEXPR bool operator!=(const field_view& rhs) const noexcept { return !(*this==rhs); }
|
||||
/// Tests for inequality (type and value); see [link mysql.values.relational this section] for
|
||||
/// more info.
|
||||
BOOST_CXX14_CONSTEXPR bool operator!=(const field_view& rhs) const noexcept
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
// TODO: hide this
|
||||
void offset_to_string_view(const std::uint8_t* buffer_first) noexcept
|
||||
@@ -126,10 +137,10 @@ public:
|
||||
ikind_ = internal_kind::string;
|
||||
repr_.string = {
|
||||
reinterpret_cast<const char*>(buffer_first) + repr_.sv_offset.offset,
|
||||
repr_.sv_offset.size
|
||||
};
|
||||
repr_.sv_offset.size};
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
enum class internal_kind
|
||||
{
|
||||
@@ -174,14 +185,25 @@ private:
|
||||
BOOST_CXX14_CONSTEXPR repr_t(float v) noexcept : float_(v) {}
|
||||
BOOST_CXX14_CONSTEXPR repr_t(double v) noexcept : double_(v) {}
|
||||
BOOST_CXX14_CONSTEXPR repr_t(date v) noexcept : date_(v.time_since_epoch().count()) {}
|
||||
BOOST_CXX14_CONSTEXPR repr_t(datetime v) noexcept : datetime_(v.time_since_epoch().count()) {}
|
||||
BOOST_CXX14_CONSTEXPR repr_t(datetime v) noexcept : datetime_(v.time_since_epoch().count())
|
||||
{
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR repr_t(time v) noexcept : time_(v.count()) {}
|
||||
BOOST_CXX14_CONSTEXPR repr_t(detail::string_view_offset v) noexcept : sv_offset{v.offset(), v.size()} {}
|
||||
BOOST_CXX14_CONSTEXPR repr_t(detail::string_view_offset v) noexcept
|
||||
: sv_offset{v.offset(), v.size()}
|
||||
{
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR repr_t(const detail::field_impl* v) noexcept : field_ptr(v) {}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::string_view get_string() const noexcept { return boost::string_view(string.ptr, string.size); }
|
||||
BOOST_CXX14_CONSTEXPR date get_date() const noexcept { return date(date::duration(date_));}
|
||||
BOOST_CXX14_CONSTEXPR datetime get_datetime() const noexcept { return datetime(datetime::duration(datetime_)); }
|
||||
BOOST_CXX14_CONSTEXPR boost::string_view get_string() const noexcept
|
||||
{
|
||||
return boost::string_view(string.ptr, string.size);
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR date get_date() const noexcept { return date(date::duration(date_)); }
|
||||
BOOST_CXX14_CONSTEXPR datetime get_datetime() const noexcept
|
||||
{
|
||||
return datetime(datetime::duration(datetime_));
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR time get_time() const noexcept { return time(time_); }
|
||||
BOOST_CXX14_CONSTEXPR detail::string_view_offset get_sv_offset() const noexcept
|
||||
{
|
||||
@@ -189,12 +211,15 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
internal_kind ikind_ { internal_kind::null };
|
||||
internal_kind ikind_{internal_kind::null};
|
||||
repr_t repr_;
|
||||
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const field_view& v);
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool is_field_ptr() const noexcept { return ikind_ == internal_kind::field_ptr; }
|
||||
BOOST_CXX14_CONSTEXPR bool is_field_ptr() const noexcept
|
||||
{
|
||||
return ikind_ == internal_kind::field_ptr;
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR inline void check_kind(internal_kind expected) const;
|
||||
};
|
||||
|
||||
@@ -211,7 +236,6 @@ private:
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& os, const field_view& v);
|
||||
|
||||
|
||||
/**
|
||||
* \relates value
|
||||
* \brief Creates an array of [reflink value]s out of the passed in arguments.
|
||||
@@ -221,10 +245,9 @@ inline std::ostream& operator<<(std::ostream& os, const field_view& v);
|
||||
template <class... Types>
|
||||
BOOST_CXX14_CONSTEXPR std::array<field_view, sizeof...(Types)> make_field_views(Types&&... args);
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/mysql/impl/field_view.hpp>
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,13 +8,15 @@
|
||||
#ifndef BOOST_MYSQL_HANDSHAKE_PARAMS_HPP
|
||||
#define BOOST_MYSQL_HANDSHAKE_PARAMS_HPP
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/mysql/collation.hpp>
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
|
||||
/// Determines whether to use TLS for the connection or not; ignored if the underlying stream is not SSL-capable.
|
||||
/// Determines whether to use TLS for the connection or not; ignored if the underlying stream is not
|
||||
/// SSL-capable.
|
||||
enum class ssl_mode
|
||||
{
|
||||
/// Never use TLS
|
||||
@@ -27,7 +29,6 @@ enum class ssl_mode
|
||||
require
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Parameters defining how to perform the handshake
|
||||
* with a MySQL server. See [link mysql.connparams this section]
|
||||
@@ -40,6 +41,7 @@ class handshake_params
|
||||
boost::string_view database_;
|
||||
collation connection_collation_;
|
||||
ssl_mode ssl_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief Initializing constructor
|
||||
@@ -47,8 +49,9 @@ public:
|
||||
* \param password Password for that username, possibly empty.
|
||||
* \param db Database name to use, or empty string for no database (this is the default).
|
||||
* \param connection_col [reflink2 collation Collation] to use for the connection.
|
||||
* Impacts how text queries and prepared statements are interpreted. Defaults to utf8_general_ci.
|
||||
* \param mode The [reflink ssl_mode] to use with this connection; ignored if the connection does not support SSL.
|
||||
* Impacts how text queries and prepared statements are interpreted. Defaults to
|
||||
* utf8_general_ci. \param mode The [reflink ssl_mode] to use with this connection; ignored if
|
||||
* the connection does not support SSL.
|
||||
*/
|
||||
handshake_params(
|
||||
boost::string_view username,
|
||||
@@ -56,12 +59,12 @@ public:
|
||||
boost::string_view db = "",
|
||||
collation connection_col = collation::utf8_general_ci,
|
||||
ssl_mode mode = ssl_mode::require
|
||||
) :
|
||||
username_(username),
|
||||
password_(password),
|
||||
database_(db),
|
||||
connection_collation_(connection_col),
|
||||
ssl_(mode)
|
||||
)
|
||||
: username_(username),
|
||||
password_(password),
|
||||
database_(db),
|
||||
connection_collation_(connection_col),
|
||||
ssl_(mode)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -96,9 +99,7 @@ public:
|
||||
void set_ssl(ssl_mode value) noexcept { ssl_ = value; }
|
||||
};
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_CONNECTION_PARAMS_HPP_ */
|
||||
|
||||
@@ -10,19 +10,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/row.hpp>
|
||||
#include <boost/mysql/connection.hpp>
|
||||
#include <boost/mysql/statement_base.hpp>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/close_connection.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/handshake.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/prepare_statement.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>
|
||||
#include <boost/mysql/resultset_base.hpp>
|
||||
#include <boost/mysql/row.hpp>
|
||||
#include <boost/mysql/statement_base.hpp>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
// connect
|
||||
template <class Stream>
|
||||
@@ -53,12 +54,8 @@ void boost::mysql::connection<Stream>::connect(
|
||||
template <class Stream>
|
||||
template <
|
||||
class EndpointType,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code)
|
||||
)
|
||||
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_connect(
|
||||
const EndpointType& endpoint,
|
||||
const handshake_params& params,
|
||||
@@ -76,7 +73,6 @@ boost::mysql::connection<Stream>::async_connect(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// handshake
|
||||
template <class Stream>
|
||||
void boost::mysql::connection<Stream>::handshake(
|
||||
@@ -90,9 +86,7 @@ void boost::mysql::connection<Stream>::handshake(
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::connection<Stream>::handshake(
|
||||
const handshake_params& params
|
||||
)
|
||||
void boost::mysql::connection<Stream>::handshake(const handshake_params& params)
|
||||
{
|
||||
detail::error_block blk;
|
||||
handshake(params, blk.err, blk.info);
|
||||
@@ -101,10 +95,7 @@ void boost::mysql::connection<Stream>::handshake(
|
||||
|
||||
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_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::connection<Stream>::async_handshake(
|
||||
const handshake_params& params,
|
||||
error_info& output_info,
|
||||
@@ -145,13 +136,8 @@ void boost::mysql::connection<Stream>::query(
|
||||
}
|
||||
|
||||
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)
|
||||
)
|
||||
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_query(
|
||||
boost::string_view query_string,
|
||||
resultset<Stream>& result,
|
||||
@@ -169,7 +155,6 @@ boost::mysql::connection<Stream>::async_query(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Prepare statement
|
||||
template <class Stream>
|
||||
void boost::mysql::connection<Stream>::prepare_statement(
|
||||
@@ -195,13 +180,8 @@ void boost::mysql::connection<Stream>::prepare_statement(
|
||||
}
|
||||
|
||||
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)
|
||||
)
|
||||
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_prepare_statement(
|
||||
boost::string_view stmt,
|
||||
statement<Stream>& output,
|
||||
@@ -221,10 +201,7 @@ boost::mysql::connection<Stream>::async_prepare_statement(
|
||||
|
||||
// Close
|
||||
template <class Stream>
|
||||
void boost::mysql::connection<Stream>::close(
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
void boost::mysql::connection<Stream>::close(error_code& err, error_info& info)
|
||||
{
|
||||
detail::clear_errors(err, info);
|
||||
detail::close_connection(get_channel(), err, info);
|
||||
@@ -240,14 +217,8 @@ void boost::mysql::connection<Stream>::close()
|
||||
|
||||
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(
|
||||
error_info& output_info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::connection<Stream>::async_close(error_info& output_info, CompletionToken&& token)
|
||||
{
|
||||
output_info.clear();
|
||||
return detail::async_close_connection(
|
||||
@@ -258,10 +229,7 @@ boost::mysql::connection<Stream>::async_close(
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
void boost::mysql::connection<Stream>::quit(
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
void boost::mysql::connection<Stream>::quit(error_code& err, error_info& info)
|
||||
{
|
||||
detail::clear_errors(err, info);
|
||||
detail::quit_connection(get_channel(), err, info);
|
||||
@@ -277,14 +245,8 @@ void boost::mysql::connection<Stream>::quit()
|
||||
|
||||
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_quit(
|
||||
error_info& output_info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
|
||||
boost::mysql::connection<Stream>::async_quit(error_info& output_info, CompletionToken&& token)
|
||||
{
|
||||
output_info.clear();
|
||||
return detail::async_quit_connection(
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/impl/error_descriptions.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost {
|
||||
@@ -25,18 +27,16 @@ struct is_error_code_enum<mysql::errc>
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
} // system
|
||||
} // namespace system
|
||||
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
inline const char* error_to_string(errc error) noexcept
|
||||
{
|
||||
auto it = std::find_if(
|
||||
std::begin(all_errors),
|
||||
std::end(all_errors),
|
||||
[error] (error_entry ent) { return error == ent.value; }
|
||||
);
|
||||
auto it = std::find_if(std::begin(all_errors), std::end(all_errors), [error](error_entry ent) {
|
||||
return error == ent.value;
|
||||
});
|
||||
return it == std::end(all_errors) ? "<unknown error>" : it->message;
|
||||
}
|
||||
|
||||
@@ -62,10 +62,7 @@ inline mysql_error_category_t& get_mysql_error_category() noexcept
|
||||
|
||||
inline mysql_error_category_t mysql_error_category;
|
||||
|
||||
inline mysql_error_category_t& get_mysql_error_category() noexcept
|
||||
{
|
||||
return mysql_error_category;
|
||||
}
|
||||
inline mysql_error_category_t& get_mysql_error_category() noexcept { return mysql_error_category; }
|
||||
|
||||
#endif
|
||||
|
||||
@@ -92,24 +89,18 @@ struct error_block
|
||||
void check() { detail::check_error_code(err, info); }
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
inline std::ostream& boost::mysql::operator<<(
|
||||
std::ostream& os,
|
||||
errc value
|
||||
)
|
||||
inline std::ostream& boost::mysql::operator<<(std::ostream& os, errc value)
|
||||
{
|
||||
return os << detail::error_to_string(value);
|
||||
}
|
||||
|
||||
inline boost::mysql::error_code boost::mysql::make_error_code(
|
||||
errc error
|
||||
)
|
||||
inline boost::mysql::error_code boost::mysql::make_error_code(errc error)
|
||||
{
|
||||
return boost::system::error_code(static_cast<int>(error), detail::get_mysql_error_category());
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,34 +10,30 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/field.hpp>
|
||||
#include <boost/mysql/detail/protocol/date.hpp>
|
||||
#include <boost/mysql/bad_field_access.hpp>
|
||||
#include <boost/mysql/detail/protocol/date.hpp>
|
||||
#include <boost/mysql/field.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
void boost::mysql::field::from_view(
|
||||
const field_view& fv
|
||||
)
|
||||
void boost::mysql::field::from_view(const field_view& fv)
|
||||
{
|
||||
switch (fv.kind())
|
||||
{
|
||||
case field_kind::null: repr_.data.emplace<detail::field_impl::null_t>(); break;
|
||||
case field_kind::int64: repr_.data.emplace<std::int64_t>(fv.get_int64()); break;
|
||||
case field_kind::uint64: repr_.data.emplace<std::uint64_t>(fv.get_uint64()); break;
|
||||
case field_kind::string: repr_.data.emplace<std::string>(fv.get_string()); break;
|
||||
case field_kind::float_: repr_.data.emplace<float>(fv.get_float()); break;
|
||||
case field_kind::double_: repr_.data.emplace<double>(fv.get_double()); break;
|
||||
case field_kind::date: repr_.data.emplace<date>(fv.get_date()); break;
|
||||
case field_kind::datetime: repr_.data.emplace<datetime>(fv.get_datetime()); break;
|
||||
case field_kind::time: repr_.data.emplace<time>(fv.get_time()); break;
|
||||
case field_kind::null: repr_.data.emplace<detail::field_impl::null_t>(); break;
|
||||
case field_kind::int64: repr_.data.emplace<std::int64_t>(fv.get_int64()); break;
|
||||
case field_kind::uint64: repr_.data.emplace<std::uint64_t>(fv.get_uint64()); break;
|
||||
case field_kind::string: repr_.data.emplace<std::string>(fv.get_string()); break;
|
||||
case field_kind::float_: repr_.data.emplace<float>(fv.get_float()); break;
|
||||
case field_kind::double_: repr_.data.emplace<double>(fv.get_double()); break;
|
||||
case field_kind::date: repr_.data.emplace<date>(fv.get_date()); break;
|
||||
case field_kind::datetime: repr_.data.emplace<datetime>(fv.get_datetime()); break;
|
||||
case field_kind::time: repr_.data.emplace<time>(fv.get_time()); break;
|
||||
}
|
||||
}
|
||||
|
||||
inline std::ostream& boost::mysql::operator<<(
|
||||
std::ostream& os,
|
||||
const field& value
|
||||
)
|
||||
inline std::ostream& boost::mysql::operator<<(std::ostream& os, const field& value)
|
||||
{
|
||||
return os << field_view(value);
|
||||
}
|
||||
|
||||
@@ -11,12 +11,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/field_kind.hpp>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
inline std::ostream& boost::mysql::operator<<(
|
||||
std::ostream& os,
|
||||
boost::mysql::field_kind v
|
||||
)
|
||||
inline std::ostream& boost::mysql::operator<<(std::ostream& os, boost::mysql::field_kind v)
|
||||
{
|
||||
switch (v)
|
||||
{
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
#include <boost/mysql/detail/protocol/date.hpp>
|
||||
#include <boost/mysql/bad_field_access.hpp>
|
||||
#include <ostream>
|
||||
#include <boost/mysql/detail/protocol/date.hpp>
|
||||
#include <boost/mysql/field_view.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <ostream>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -24,7 +25,7 @@ inline std::ostream& print_date(std::ostream& os, const date& value)
|
||||
{
|
||||
assert(value >= min_date && value <= max_date);
|
||||
auto ymd = detail::days_to_ymd(value.time_since_epoch().count());
|
||||
char buffer [32] {};
|
||||
char buffer[32]{};
|
||||
snprintf(buffer, sizeof(buffer), "%04d-%02u-%02u", ymd.years, ymd.month, ymd.day);
|
||||
os << buffer;
|
||||
return os;
|
||||
@@ -34,14 +35,17 @@ inline std::ostream& print_time(std::ostream& os, const time& value)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
assert(value >= min_time && value <= max_time);
|
||||
char buffer [64] {};
|
||||
char buffer[64]{};
|
||||
const char* sign = value < microseconds(0) ? "-" : "";
|
||||
auto num_micros = value % seconds(1);
|
||||
auto num_secs = duration_cast<seconds>(value % minutes(1) - num_micros);
|
||||
auto num_mins = duration_cast<minutes>(value % hours(1) - num_secs);
|
||||
auto num_hours = duration_cast<hours>(value - num_mins);
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%s%02d:%02u:%02u.%06u",
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"%s%02d:%02u:%02u.%06u",
|
||||
sign,
|
||||
static_cast<int>(std::abs(num_hours.count())),
|
||||
static_cast<unsigned>(std::abs(num_mins.count())),
|
||||
@@ -60,146 +64,98 @@ inline std::ostream& print_datetime(std::ostream& os, const datetime& value)
|
||||
if (date_part > value)
|
||||
date_part -= days(1);
|
||||
auto tod = value - date_part;
|
||||
print_date(os, date_part); // date part
|
||||
os << ' '; // separator
|
||||
print_time(os, duration_cast<time>(tod)); // time of day part
|
||||
print_date(os, date_part); // date part
|
||||
os << ' '; // separator
|
||||
print_time(os, duration_cast<time>(tod)); // time of day part
|
||||
return os;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
signed char v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::int64),
|
||||
repr_(std::int64_t(v))
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(signed char v) noexcept
|
||||
: ikind_(internal_kind::int64), repr_(std::int64_t(v))
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
short v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::int64),
|
||||
repr_(std::int64_t(v))
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(short v) noexcept
|
||||
: ikind_(internal_kind::int64), repr_(std::int64_t(v))
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
int v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::int64),
|
||||
repr_(std::int64_t(v))
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(int v) noexcept
|
||||
: ikind_(internal_kind::int64), repr_(std::int64_t(v))
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
long v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::int64),
|
||||
repr_(std::int64_t(v))
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(long v) noexcept
|
||||
: ikind_(internal_kind::int64), repr_(std::int64_t(v))
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
long long v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::int64),
|
||||
repr_(std::int64_t(v))
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(long long v) noexcept
|
||||
: ikind_(internal_kind::int64), repr_(std::int64_t(v))
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
unsigned char v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::uint64),
|
||||
repr_(std::uint64_t(v))
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(unsigned char v) noexcept
|
||||
: ikind_(internal_kind::uint64), repr_(std::uint64_t(v))
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
unsigned short v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::uint64),
|
||||
repr_(std::uint64_t(v))
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(unsigned short v) noexcept
|
||||
: ikind_(internal_kind::uint64), repr_(std::uint64_t(v))
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
unsigned int v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::uint64),
|
||||
repr_(std::uint64_t(v))
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(unsigned int v) noexcept
|
||||
: ikind_(internal_kind::uint64), repr_(std::uint64_t(v))
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
unsigned long v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::uint64),
|
||||
repr_(std::uint64_t(v))
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(unsigned long v) noexcept
|
||||
: ikind_(internal_kind::uint64), repr_(std::uint64_t(v))
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
unsigned long long v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::uint64),
|
||||
repr_(std::uint64_t(v))
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(unsigned long long v) noexcept
|
||||
: ikind_(internal_kind::uint64), repr_(std::uint64_t(v))
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
boost::string_view v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::string),
|
||||
repr_(v)
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(boost::string_view v) noexcept
|
||||
: ikind_(internal_kind::string), repr_(v)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
float v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::float_),
|
||||
repr_(v)
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(float v) noexcept
|
||||
: ikind_(internal_kind::float_), repr_(v)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
double v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::double_),
|
||||
repr_(v)
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(double v) noexcept
|
||||
: ikind_(internal_kind::double_), repr_(v)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
const date& v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::date),
|
||||
repr_(v)
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(const date& v) noexcept
|
||||
: ikind_(internal_kind::date), repr_(v)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
const datetime& v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::datetime),
|
||||
repr_(v)
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(const datetime& v) noexcept
|
||||
: ikind_(internal_kind::datetime), repr_(v)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(
|
||||
const time& v
|
||||
) noexcept :
|
||||
ikind_(internal_kind::time),
|
||||
repr_(v)
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::field_view::field_view(const time& v) noexcept
|
||||
: ikind_(internal_kind::time), repr_(v)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::mysql::field_kind boost::mysql::field_view::kind() const noexcept
|
||||
BOOST_CXX14_CONSTEXPR inline boost::mysql::field_kind boost::mysql::field_view::kind(
|
||||
) const noexcept
|
||||
{
|
||||
switch (ikind_)
|
||||
{
|
||||
@@ -214,12 +170,11 @@ BOOST_CXX14_CONSTEXPR inline boost::mysql::field_kind boost::mysql::field_view::
|
||||
case internal_kind::time: return field_kind::time;
|
||||
case internal_kind::field_ptr: return repr_.field_ptr->kind();
|
||||
// sv_offset values must be converted via offset_to_string_view before calling any other fn
|
||||
default: return field_kind::null;
|
||||
default: return field_kind::null;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR std::int64_t
|
||||
boost::mysql::field_view::as_int64() const
|
||||
BOOST_CXX14_CONSTEXPR std::int64_t boost::mysql::field_view::as_int64() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<std::int64_t>();
|
||||
@@ -227,8 +182,7 @@ boost::mysql::field_view::as_int64() const
|
||||
return repr_.int64;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR std::uint64_t
|
||||
boost::mysql::field_view::as_uint64() const
|
||||
BOOST_CXX14_CONSTEXPR std::uint64_t boost::mysql::field_view::as_uint64() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<std::uint64_t>();
|
||||
@@ -236,8 +190,7 @@ boost::mysql::field_view::as_uint64() const
|
||||
return repr_.uint64;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::string_view
|
||||
boost::mysql::field_view::as_string() const
|
||||
BOOST_CXX14_CONSTEXPR boost::string_view boost::mysql::field_view::as_string() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<std::string>();
|
||||
@@ -245,8 +198,7 @@ boost::mysql::field_view::as_string() const
|
||||
return repr_.get_string();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR float
|
||||
boost::mysql::field_view::as_float() const
|
||||
BOOST_CXX14_CONSTEXPR float boost::mysql::field_view::as_float() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<float>();
|
||||
@@ -254,8 +206,7 @@ boost::mysql::field_view::as_float() const
|
||||
return repr_.float_;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR double
|
||||
boost::mysql::field_view::as_double() const
|
||||
BOOST_CXX14_CONSTEXPR double boost::mysql::field_view::as_double() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<double>();
|
||||
@@ -263,8 +214,7 @@ boost::mysql::field_view::as_double() const
|
||||
return repr_.double_;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::date
|
||||
boost::mysql::field_view::as_date() const
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::date boost::mysql::field_view::as_date() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<date>();
|
||||
@@ -272,8 +222,7 @@ boost::mysql::field_view::as_date() const
|
||||
return repr_.get_date();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::datetime
|
||||
boost::mysql::field_view::as_datetime() const
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::datetime boost::mysql::field_view::as_datetime() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<datetime>();
|
||||
@@ -281,8 +230,7 @@ boost::mysql::field_view::as_datetime() const
|
||||
return repr_.get_datetime();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::time
|
||||
boost::mysql::field_view::as_time() const
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::time boost::mysql::field_view::as_time() const
|
||||
{
|
||||
if (is_field_ptr())
|
||||
return repr_.field_ptr->as<time>();
|
||||
@@ -290,71 +238,61 @@ boost::mysql::field_view::as_time() const
|
||||
return repr_.get_time();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR std::int64_t
|
||||
boost::mysql::field_view::get_int64() const noexcept
|
||||
BOOST_CXX14_CONSTEXPR std::int64_t boost::mysql::field_view::get_int64() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<std::int64_t>() : repr_.int64;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR std::uint64_t
|
||||
boost::mysql::field_view::get_uint64() const noexcept
|
||||
BOOST_CXX14_CONSTEXPR std::uint64_t boost::mysql::field_view::get_uint64() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<std::uint64_t>() : repr_.uint64;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::string_view
|
||||
boost::mysql::field_view::get_string() const noexcept
|
||||
BOOST_CXX14_CONSTEXPR boost::string_view boost::mysql::field_view::get_string() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? boost::string_view(repr_.field_ptr->get<std::string>()) : repr_.get_string();
|
||||
return is_field_ptr() ? boost::string_view(repr_.field_ptr->get<std::string>())
|
||||
: repr_.get_string();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR float
|
||||
boost::mysql::field_view::get_float() const noexcept
|
||||
BOOST_CXX14_CONSTEXPR float boost::mysql::field_view::get_float() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<float>() : repr_.float_;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR double
|
||||
boost::mysql::field_view::get_double() const noexcept
|
||||
BOOST_CXX14_CONSTEXPR double boost::mysql::field_view::get_double() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<double>() : repr_.double_;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::date
|
||||
boost::mysql::field_view::get_date() const noexcept
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::date boost::mysql::field_view::get_date() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<date>() : repr_.get_date();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::datetime
|
||||
boost::mysql::field_view::get_datetime() const noexcept
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::datetime boost::mysql::field_view::get_datetime() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<datetime>() : repr_.get_datetime();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::time
|
||||
boost::mysql::field_view::get_time() const noexcept
|
||||
BOOST_CXX14_CONSTEXPR boost::mysql::time boost::mysql::field_view::get_time() const noexcept
|
||||
{
|
||||
return is_field_ptr() ? repr_.field_ptr->get<time>() : repr_.get_time();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR void boost::mysql::field_view::check_kind(
|
||||
internal_kind expected
|
||||
) const
|
||||
BOOST_CXX14_CONSTEXPR void boost::mysql::field_view::check_kind(internal_kind expected) const
|
||||
{
|
||||
if (ikind_ != expected)
|
||||
throw bad_field_access();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool boost::mysql::field_view::operator==(
|
||||
const field_view& rhs
|
||||
BOOST_CXX14_CONSTEXPR bool boost::mysql::field_view::operator==(const field_view& rhs
|
||||
) const noexcept
|
||||
{
|
||||
// Make operator== work for types not representable by field_kind
|
||||
if (ikind_ == internal_kind::sv_offset)
|
||||
{
|
||||
return rhs.ikind_ == internal_kind::sv_offset &&
|
||||
repr_.get_sv_offset() == rhs.repr_.get_sv_offset();
|
||||
repr_.get_sv_offset() == rhs.repr_.get_sv_offset();
|
||||
}
|
||||
|
||||
auto k = kind(), rhs_k = rhs.kind();
|
||||
@@ -387,31 +325,23 @@ BOOST_CXX14_CONSTEXPR bool boost::mysql::field_view::operator==(
|
||||
}
|
||||
else
|
||||
return false;
|
||||
case field_kind::string:
|
||||
return rhs_k == field_kind::string && get_string() == rhs.get_string();
|
||||
case field_kind::float_:
|
||||
return rhs_k == field_kind::float_ && get_float() == rhs.get_float();
|
||||
case field_kind::string: return rhs_k == field_kind::string && get_string() == rhs.get_string();
|
||||
case field_kind::float_: return rhs_k == field_kind::float_ && get_float() == rhs.get_float();
|
||||
case field_kind::double_:
|
||||
return rhs_k == field_kind::double_ && get_double() == rhs.get_double();
|
||||
case field_kind::date:
|
||||
return rhs_k == field_kind::date && get_date() == rhs.get_date();
|
||||
case field_kind::date: return rhs_k == field_kind::date && get_date() == rhs.get_date();
|
||||
case field_kind::datetime:
|
||||
return rhs_k == field_kind::datetime && get_datetime() == rhs.get_datetime();
|
||||
case field_kind::time:
|
||||
return rhs_k == field_kind::time && get_time() == rhs.get_time();
|
||||
case field_kind::time: return rhs_k == field_kind::time && get_time() == rhs.get_time();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream& boost::mysql::operator<<(
|
||||
std::ostream& os,
|
||||
const field_view& value
|
||||
)
|
||||
inline std::ostream& boost::mysql::operator<<(std::ostream& os, const field_view& value)
|
||||
{
|
||||
// Make operator<< work for detail::string_view_offset types
|
||||
if (value.ikind_ == field_view::internal_kind::sv_offset)
|
||||
return os << "<sv_offset>";
|
||||
|
||||
|
||||
switch (value.kind())
|
||||
{
|
||||
case field_kind::null: return os << "<NULL>";
|
||||
@@ -428,13 +358,9 @@ inline std::ostream& boost::mysql::operator<<(
|
||||
|
||||
template <class... Types>
|
||||
BOOST_CXX14_CONSTEXPR std::array<boost::mysql::field_view, sizeof...(Types)>
|
||||
boost::mysql::make_field_views(
|
||||
Types&&... args
|
||||
)
|
||||
boost::mysql::make_field_views(Types&&... args)
|
||||
{
|
||||
return std::array<field_view, sizeof...(Types)>{{field_view(std::forward<Types>(args))...}};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,9 +16,7 @@ namespace boost {
|
||||
namespace mysql {
|
||||
namespace detail {
|
||||
|
||||
inline field_type compute_field_type_string(
|
||||
std::uint32_t flags
|
||||
)
|
||||
inline field_type compute_field_type_string(std::uint32_t flags)
|
||||
{
|
||||
if (flags & column_flags::set)
|
||||
return field_type::set;
|
||||
@@ -30,9 +28,7 @@ inline field_type compute_field_type_string(
|
||||
return field_type::char_;
|
||||
}
|
||||
|
||||
inline field_type compute_field_type_var_string(
|
||||
std::uint32_t flags
|
||||
)
|
||||
inline field_type compute_field_type_var_string(std::uint32_t flags)
|
||||
{
|
||||
if (flags & column_flags::binary)
|
||||
return field_type::varbinary;
|
||||
@@ -40,9 +36,7 @@ inline field_type compute_field_type_var_string(
|
||||
return field_type::varchar;
|
||||
}
|
||||
|
||||
inline field_type compute_field_type_blob(
|
||||
std::uint32_t flags
|
||||
)
|
||||
inline field_type compute_field_type_blob(std::uint32_t flags)
|
||||
{
|
||||
if (flags & column_flags::binary)
|
||||
return field_type::blob;
|
||||
@@ -50,16 +44,12 @@ inline field_type compute_field_type_blob(
|
||||
return field_type::text;
|
||||
}
|
||||
|
||||
inline field_type compute_field_type(
|
||||
protocol_field_type protocol_type,
|
||||
std::uint32_t flags
|
||||
)
|
||||
inline field_type compute_field_type(protocol_field_type protocol_type, std::uint32_t flags)
|
||||
{
|
||||
switch (protocol_type)
|
||||
{
|
||||
case protocol_field_type::decimal:
|
||||
case protocol_field_type::newdecimal:
|
||||
return field_type::decimal;
|
||||
case protocol_field_type::newdecimal: return field_type::decimal;
|
||||
case protocol_field_type::geometry: return field_type::geometry;
|
||||
case protocol_field_type::tiny: return field_type::tinyint;
|
||||
case protocol_field_type::short_: return field_type::smallint;
|
||||
@@ -81,9 +71,9 @@ inline field_type compute_field_type(
|
||||
}
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace boost
|
||||
|
||||
inline boost::mysql::field_type boost::mysql::metadata::type() const noexcept
|
||||
{
|
||||
|
||||
@@ -10,23 +10,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mysql/resultset.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/read_all_rows.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/read_one_row.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/read_some_rows.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/read_all_rows.hpp>
|
||||
#include <boost/mysql/resultset.hpp>
|
||||
|
||||
// Read one row
|
||||
template <class Stream>
|
||||
boost::mysql::row_view boost::mysql::resultset<Stream>::read_one(
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
boost::mysql::row_view boost::mysql::resultset<Stream>::read_one(error_code& err, error_info& info)
|
||||
{
|
||||
detail::clear_errors(err, info);
|
||||
return detail::read_one_row(get_channel(), *this, err, info);
|
||||
}
|
||||
|
||||
|
||||
template <class Stream>
|
||||
boost::mysql::row_view boost::mysql::resultset<Stream>::read_one()
|
||||
{
|
||||
@@ -37,17 +33,13 @@ boost::mysql::row_view boost::mysql::resultset<Stream>::read_one()
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::row_view)
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, ::boost::mysql::row_view)
|
||||
) CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code, boost::mysql::row_view)
|
||||
)
|
||||
boost::mysql::resultset<Stream>::async_read_one(
|
||||
error_info& output_info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
boost::mysql::resultset<Stream>::async_read_one(error_info& output_info, CompletionToken&& token)
|
||||
{
|
||||
output_info.clear();
|
||||
return detail::async_read_one_row(
|
||||
@@ -60,16 +52,13 @@ boost::mysql::resultset<Stream>::async_read_one(
|
||||
|
||||
// Read some rows
|
||||
template <class Stream>
|
||||
boost::mysql::rows_view boost::mysql::resultset<Stream>::read_some(
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
boost::mysql::rows_view
|
||||
boost::mysql::resultset<Stream>::read_some(error_code& err, error_info& info)
|
||||
{
|
||||
detail::clear_errors(err, info);
|
||||
return detail::read_some_rows(get_channel(), *this, err, info);
|
||||
}
|
||||
|
||||
|
||||
template <class Stream>
|
||||
boost::mysql::rows_view boost::mysql::resultset<Stream>::read_some()
|
||||
{
|
||||
@@ -80,17 +69,14 @@ boost::mysql::rows_view boost::mysql::resultset<Stream>::read_some()
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::rows_view)
|
||||
) CompletionToken>
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, ::boost::mysql::rows_view))
|
||||
CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code, boost::mysql::rows_view)
|
||||
)
|
||||
boost::mysql::resultset<Stream>::async_read_some(
|
||||
error_info& output_info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
boost::mysql::resultset<Stream>::async_read_some(error_info& output_info, CompletionToken&& token)
|
||||
{
|
||||
output_info.clear();
|
||||
return detail::async_read_some_rows(
|
||||
@@ -103,16 +89,12 @@ boost::mysql::resultset<Stream>::async_read_some(
|
||||
|
||||
// Read all rows
|
||||
template <class Stream>
|
||||
boost::mysql::rows_view boost::mysql::resultset<Stream>::read_all(
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
boost::mysql::rows_view boost::mysql::resultset<Stream>::read_all(error_code& err, error_info& info)
|
||||
{
|
||||
detail::clear_errors(err, info);
|
||||
return detail::read_all_rows(get_channel(), *this, err, info);
|
||||
}
|
||||
|
||||
|
||||
template <class Stream>
|
||||
boost::mysql::rows_view boost::mysql::resultset<Stream>::read_all()
|
||||
{
|
||||
@@ -123,17 +105,14 @@ boost::mysql::rows_view boost::mysql::resultset<Stream>::read_all()
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
template <BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::rows_view)
|
||||
) CompletionToken>
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, ::boost::mysql::rows_view))
|
||||
CompletionToken>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(boost::mysql::error_code, boost::mysql::rows_view)
|
||||
)
|
||||
boost::mysql::resultset<Stream>::async_read_all(
|
||||
error_info& output_info,
|
||||
CompletionToken&& token
|
||||
)
|
||||
boost::mysql::resultset<Stream>::async_read_all(error_info& output_info, CompletionToken&& token)
|
||||
{
|
||||
output_info.clear();
|
||||
return detail::async_read_all_rows(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user