Linux/OSX | Windows | Coverage | Documentation |
---|---|---|---|
Boost.Mysql is a C++11 client for the MySQL database server, based on Boost.Asio. This library is in the process of being proposed for Boost.
Documentation and examples are here.
- It is fully compatible with Boost.Asio and integrates well with any other library in the Boost.Asio ecosystem (like Boost.Beast).
- It supports Boost.Asio's universal asynchronous model, which means you can go asyncrhonous using callbacks, futures or coroutines (including C++20 coroutines).
- It is written in modern C++ (C++11) and takes advantage of the latest language features and standard library additions.
- It is header only.
As this is a header-only library, you do not need to build it. However, as it has a bunch of dependencies, we suggest you use CMake to pull them in as you build your application.
Download Boost.MySQL and make it available to your CMake script (we suggest you use CMake's FetchContent module to do this), and then call add_subdirectory() on the Boost.MySQL root directory. This will look for all the required dependencies.
Finally, link your target against the Boost::mysql interface library, and you will be done!
- C++11 capable compiler (tested with gcc 5 to 11, clang 3.6 to 13 and MSVC 19.25).
- Boost.
- OpenSSL.
- CMake 3.13.0 or higher, if using CMake to build against the library (this is the preferred way).
- Tested with MySQL v5.7.29, MySQL v8.0.19, MariaDB v10.3 and MariaDB v10.5.
The current latest version is 0.1.0. Until Boost.Mysql passes its Boost formal review, the library might get non-backwards-compatible changes between minor versions. Sorry for that! Any breaking change will be listed here, together with a rationale and an upgrade guide. If you encounter any trouble, please open an issue in the repository.
This version has changed the way SSL is handled by the library to a more standard approach, similar to what Boost.Beast and Boost.Asio use. It has also introduced some naming changes. The full list of breaking changes follows:
- The
connection
object no longer uses SSL/TLS implicitly. To enable SSL/TLS, you must explicitly use aStream
type supporting SSL/TLS.- Rationale: in 0.0.x,
connection
objects created a hidden SSL stream on top of the provided stream. This approach is confusing and non-standard, and allowed little control over SSL options to the user. You were probably using SSL without knowing you were. - How to upgrade:
- If you were using
tcp_connection
orunix_connection
and you want to keep using SSL, use the newtcp_ssl_connection
orunix_ssl_connection
, instead. You will need to create aboost::asio::ssl::context
and pass it to the connection constructor. All of the examples use SSL, so you can review those. - If you were using
tcp_connection
orunix_connection
and you don't want to use SSL, you don't need to change anything. - If you were directly using the template classes
connection<Stream>
orsocket_connection<Stream>
, and you want to keep using SSL, you will need to useconnection<boost::asio::ssl::stream<Stream>>
, instead. You will need to create aboost::asio::ssl::context
and pass it to the connection constructor. - If you were directly using the template classes
connection<Stream>
orsocket_connection<Stream>
, and you don't want to use SSL, you don't need to change anything.
- If you were using
- Rationale: in 0.0.x,
- The
ssl_options
struct has been removed, in favor of its only member,ssl_mode
.- Rationale:
ssl_options
would eventually include options to be set on thessl::context
that was implicitly created byconnection
. You can now provide assl::context
with all the options, so this is no longer required. - How to upgrade:
- If you were using the struct
ssl_options(ssl_mode::xxxx)
anywhere, replace it byssl_mode::xxxx
. - If you were using
connection_params::ssl()
, this function now returns an instance ofssl_mode
, instead ofssl_options
. - Otherwise, you don't need to do anything.
- If you were using the struct
- Rationale:
- The
socket_connection
class has been removed, and its functionality has been merged intoconnection
.- Rationale:
socket_connection
added complexity with no added value. - How to upgrade: if you were explicitly using
socket_connection<MyStreamType>
, replace it byconnection<MyStreamType>
. If you were using thetcp_connection
andunix_connection
type aliases, you don't need to do anything.
- Rationale:
- Type aliases for
connection
,prepared_statement
andresultset
have moved to separate files.- Rationale: as more type aliases become available, the
connection.hpp
header would include more and more unwanted dependencies. - How to upgrade: use the new header files
tcp.hpp
,tcp_ssl.hpp
,unix.hpp
andunix_ssl.hpp
.
- Rationale: as more type aliases become available, the
- The convenience header
boost/mysql/mysql.hpp
has been moved toboost/mysql.hpp
.- Rationale: the first path was a mistake, in the first place. All other Boost libs follow the other convention.
- How to upgrade: if you were using the
boost/mysql/mysql.hpp
header, replace it byboost/mysql.hpp
. Otherwise, you don't need to do anything.
- The
prepared_statement::execute
iterator overload has been replaced by an overload taking anexecute_params
struct, encapsulating those iterators.- Rationale: this approach is more extensible. When adding further optional parameters to
execute
, we don't need to create extra overloads. - How to upgrade: replace
prepared_statement::execute(it1, it2)
calls byprepared_statement::execute(make_execute_params(it1, it2))
.
- Rationale: this approach is more extensible. When adding further optional parameters to
- The
resultset::fetch_one
,resultset::fetch_many
,resultset::fetch_all
methods have been renamed toread_one
,read_many
andread_all
.- Rationale: these functions read rows that the MySQL server has already sent. The term fetch is used in the MySQL protocol to ask the server for extra rows under certain circumstances. We would like to be able to implement this protocol feature in the future without causing massive confusion.
- How to upgrade: apply the renaming.
- There are no longer
row
s andowning_row
s. Instead, all rows now own the memory for their values and are simply calledrow
s. Theresultset::read_one
(oldresultset::fetch_one
) function now takes arow
lvalue reference and returns a boolean indicating whether a row was read or not.- Rationale: the old mechanics for
resultset::fetch_one
didn't allow for efficient composition, as the returned row was owned by theresultset
and had to be copied before further reading. With the new approach,read_many
andread_all
can be implemented in terms offetch_one
. - How to upgrade: replace loops like
while (const row* r = resultset.fetch_one()) {}
byrow r; while (resultset.fetch_one(r))
(and their async equivalents).
- Rationale: the old mechanics for
NULL
values are now represented as a custom typeboost::mysql::null_t
(which is an alias forboost::variant2::monostate
), instead ofstd::nullptr_t
.- Rationale: relational operators like
<
don't work forstd::nullptr_t
values, which means you can't have astd::set<value>
.boost::variant2::monostate
is the right tool to represent values likeNULL
. - How to upgrade:
- If you were using
boost::variant2::visit
on the underlying variant returned byvalue::to_variant
, you need to add an overload taking anull_t
to the visitor function. - If you were using
value::is<std::nullptr_t>
, replace it byvalue::is_null
orvalue::is<null_t>
.
- If you were using
- Rationale: relational operators like
value::get
no longer throwsboost::variant2::bad_variant_access
, but a custom exception typeboost::mysql::bad_value_access
.- Rationale: it provides finer control over exception handling.
- How to upgrade: if you were catching
boost::variant2::bad_variant_access
as a result of avalue::get
call, replace the exception type in thecatch
clause byboost::mysql::bad_value_access
.
Currently implemented:
- Text queries (execution of text SQL queries and data retrieval). MySQL refers to this as the "text protocol", as all information is passed using text (as opposed to prepared statements, see below).
- Prepared statements. MySQL refers to this as the "binary protocol", as the result of executing a prepared statement is sent in binary format rather than in text.
- Authentication methods (authentication plugins): mysql_native_password and caching_sha2_password. These are the default methods in MySQL 5 and MySQL 8, respectively.
- Encrypted connections (TLS).
- TCP and UNIX socket connections. The implementation is based on Boost.Asio SyncStream and AsyncStream concepts, so it is generic and can be used with any stream that fulfills these concept's requirements. There are user-friendly typedefs and regression tests for TCP and UNIX socket streams.
Yet to be done (but it is on our list - PRs welcome):
- Further authentication methods: sha256_password
- Multi-resultset: being able to specify several semicolon-separated queries.